连字符/破折号参数对PowerShell意味着什么?

Mar*_*ryl 9 powershell

我发现,如果仅在Windows 10上将破折号传递给PowerShell 5.1脚本的参数,例如:

powershell.exe -File Test.ps1 -
Run Code Online (Sandbox Code Playgroud)

我收到一条奇怪的错误消息:

C:\ path \ Test.ps1:无法处理参数,因为参数“名称”的值无效。更改“名称”参数的值,然后再次运行该操作。

  • CategoryInfo:InvalidArgument:(:) [Test.ps1],PSArgumentException
  • FullyQualifiedErrorId:Argument,Test.ps1

Test.ps1只:

echo "foo"
Run Code Online (Sandbox Code Playgroud)

我遇到的实际问题是,当脚本声明任何强制性参数时:

param (
    [Parameter(Mandatory)]
    $value
)

echo "foo"
Run Code Online (Sandbox Code Playgroud)

然后以相同的方式(带有-参数)执行脚本完全没有任何作用。无输出。没有错误讯息。它只是挂了几秒钟。然后控件返回到命令提示符。

echo "foo"
Run Code Online (Sandbox Code Playgroud)

-对PowerShell(5.1)意味着什么?


相反,在Windows 7上使用PowerShell 2.0,在这种情况下,我可以使用脚本:

param (
    [Parameter(Mandatory)]
    $value
)

echo "foo"
Run Code Online (Sandbox Code Playgroud)

有什么意义(缺少必需的参数)。

在没有强制性参数声明的情况下,脚本可以工作(将其打印输出):

C:\path>powershell.exe -File Test.ps1 -

C:\path>_
Run Code Online (Sandbox Code Playgroud)

mkl*_*nt0 1

该行为应被视为错误- 开头-但不是有效参数名称的内容应作为位置参数传递,而不是报告错误。

该错误影响:

  • Windows PowerShell(自 v5.1.18362.145 起)- 目前尚不清楚是否会进行修复。

    • 正如您所说,您是否(a)收到错误消息... the value of argument "name" is not valid ...)或(b)-悄悄忽略取决于您的参数是否具有参数属性,例如 [Parameter(Mandatory)][1]和/或您的param()块具有[CmdletBinding()]属性(如果是这样,( b) 适用)。
  • PowerShell Core 6.x - 也就是说,该问题将在 v7 中得到解决(截至撰写本文时当前版本:v7.0.0-preview.3);我不知道 6.2.2(截至撰写本文时的稳定版本)是否会得到修复 - 我们将看看您在 GitHub 上提交的错误报告会发生什么情况。


至于解决方法(在 PowerShell Core 中类似):

使用-Command而不是-File.

虽然这改变了命令行解析方式的语义[2],但在像这样的简单情况下,差异并不重要:

C:\> powershell -Command ./Test.ps1 -  # note the "./"
Run Code Online (Sandbox Code Playgroud)

请注意./,因为使用-Command( -c) 会使 PowerShell 解析参数,就像它们是 PowerShell 代码一样,并且仅适用按文件名重新执行脚本的常见限制(为了防止意外执行当前目录中的文件,您需要一个路径组件来显式表示该意图,因此需要前缀./or )。.\

如果您的脚本文件路径需要引用,则必须使用 quoting 和 prepend &(调用运算符);例如:

C:\> powershell -Command "& \"./Test.ps1\" -"
Run Code Online (Sandbox Code Playgroud)

[1][Parameter()]向声明的参数添加属性隐式地使封闭的脚本/函数成为高级脚本/函数,在这种情况下,应用不同的解析规则。该[CmdletBinding[]属性应用于param(...)整个块,明确地将脚本/函数标记为高级脚本/函数。

[2]有关解析方式和参数之间的差异,请参阅此答案-File-Command