本地计算机上带有 FilePath 的 PowerShell Invoke-Command - 模糊参数错误?

Big*_*ary 4 powershell invoke-command

我想使用 Invoke-Command 在本地计算机上的文件中运行脚本,以便我可以使用 -ArgumentList 传入参数。我遇到了一个我不明白的错误,所以我简化了我的命令。当我这样做时:

Invoke-Command -FilePath 'getprocess.ps1'
Run Code Online (Sandbox Code Playgroud)

getprocess.ps1的内容是:

Get-Process
Run Code Online (Sandbox Code Playgroud)

我收到的错误消息是:

Invoke-Command :无法使用指定的命名参数解析参数集。

行:1 字符:1

+ 调用命令 -FilePath 'getprocess.ps1'

+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

+ CategoryInfo : InvalidArgument: (:) [Invoke-Command], ParameterBindingException

+FullyQualifiedErrorId:AmbigouslyParameterSet、Microsoft.PowerShell.Commands.InvokeCommandCommand

我对这个错误消息感到困惑。这是什么意思?我该如何让它发挥作用?

mkl*_*nt0 7

长话短说:博士

  • 一般来说,不要用于Invoke-Command本地调用-虽然技术上可行,但只有一种特定的用例需要这样做(见下文)。

  • 相反,直接调用脚本

.\getprocess.ps1
Run Code Online (Sandbox Code Playgroud)

注意:与 不同的是cmd.exe,PowerShell 在设计上需要.\执行位于当前目录中的可执行文件。也就是说,为了避免意外执行当前目录中而不是从 中列出的目录中执行的可执行文件,$env:PathPowerShell 作为一项安全功能,要求您显式发出在当前目录 ( .) 中执行某些内容的意图。

对于脚本块( { ... }),请使用&调用运算符(例如,& { Get-Date })。

仅出于语法原因,如果将脚本文件路径指定为带引号的路径(例如,)和/或路径涉及变量引用(例如, ),则在某些情况下您还需要脚本文件路径。&& '.\getprocess.ps1'
& $HOME\getprocess.ps1

(另外,. 这两种情况下都需要点源运算符,以便直接在调用者的作用域而不是子作用域中执行脚本[块])。


请注意,从技术上讲,您可以将传递脚本块到(parameter ) 与调用本地脚本结合起来Invoke-Command-ScriptBlock

.\getprocess.ps1
Run Code Online (Sandbox Code Playgroud)

与直接调用相比,该方法速度较慢并且没有任何优势
.\getprocess.ps1& .\getprocess.ps1

然而,有一种可能的用例

如果脚本不是高级脚本,并且您想利用流输出收集 通用参数,例如(如果调用的脚本或函数是高级脚本,则它本身支持这些通用参数)。Invoke-Command-ErrorVariable

# The script block positionally binds to the -ScriptBlock parameter.
# This is essentially the more expensive equivalent of:
#     & .\getprocess.ps1
Invoke-Command { .\getprocess.ps1 }
Run Code Online (Sandbox Code Playgroud)

警告:至少从 PowerShell 7.2 开始,Invoke-Command不会公共-ErrorAction参数应用于脚本块中发生的错误,因此它不能用于控制错误处理;例如,-ErrorAction Stop对脚本块中的命令没有影响。


至于你尝试过的

事实上,正如您在自己的答案中指出的那样,-FilePath 必须
-ComputerName与参数结合使用
(不幸的是错误消息是如此通用)。

  • 更一般地说,必须与请求远程执行的任何参数-FilePath 结合使用,其中包括-Session-ConnectionUri-VmId/ -VmName、以及(在类 Unix 平台上)-HostName、 和-SSHConnection

参数的目的-FilePath*.ps1本地脚本(文件)内容复制到远程计算机以在远程计算机执行。也就是说,它是执行(仅)在远程计算机上本地可用的脚本代码的便捷机制。

虽然从技术上讲,您可以通过(或者更简单地说,通过/ )定位本地计算机-ComputerName localhost,但这并不等于本地调用-ComputerName .-cn .

每当-ComputerName指定时 - 即使使用-ComputerName localhost- PowerShell 的远程处理基础设施也会被使用,这具有重大影响

  • 目标计算机(即使是本地计算机)必须设置为 PowerShell 远程处理 - 请参阅about_Remote_Requirements

  • 如果您专门针对本地计算机,则必须在提升的会话中运行(以管理员身份运行)。

  • 执行将比直接(本地)调用慢得多。

  • 考虑到通过 PowerShell 基于 XML 的序列化基础设施进行跨进程封送,输入和输出数据的类型保真度可能会丢失 - 请参阅此答案


也就是说,如果目的是在本地测试脚本的远程执行,并且将本地计算机设置为远程处理目标,那么使用-ComputerName localhost( -ComputerName ./ -cn .) 就非常有意义,因为 PowerShell 的远程处理基础设施也以相同的方式参与其中这将是一次真正的远程调用。

但请注意,此类“环回远程”调用需要提升(以管理员身份运行)。