14

我正在编写一个 PowerShell 脚本,它是 .exe 的包装器。我想要一些可选的脚本参数,并将其余的直接传递给 exe。这是一个测试脚本:

param (
    [Parameter(Mandatory=$False)] [string] $a = "DefaultA"
   ,[parameter(ValueFromRemainingArguments=$true)][string[]]$ExeParams   # must be string[] - otherwise .exe invocation will quote
)

Write-Output ("a=" + ($a) + "  ExeParams:") $ExeParams

如果我使用命名参数运行,一切都很好:

C:\ > powershell /command \temp\a.ps1 -a A This-should-go-to-exeparams This-also
a=A  ExeParams:
This-should-go-to-exeparams
This-also

但是,如果我尝试省略我的参数,则会将第一个未命名的参数分配给它:

C:\ > powershell /command \temp\a.ps1 This-should-go-to-exeparams This-also
a=This-should-go-to-exeparams  ExeParams:
This-also

我希望:

a=DefaultA ExeParams:
This-should-go-to-exeparams
This-also

我尝试添加Position=0到参数,但这会产生相同的结果。

有没有办法做到这一点?
也许不同的参数方案?

4

2 回答 2

9

默认情况下,所有函数参数都是位置参数。Windows PowerShell 按照在函数中声明参数的顺序将位置编号分配给参数。要禁用此功能,请将属性的PositionalBinding参数值设置为。CmdletBinding$False

看看如何在 PowerShell 中禁用位置参数绑定

function Test-PositionalBinding
{
    [CmdletBinding(PositionalBinding=$false)]
    param(
       $param1,$param2
    )

    Write-Host param1 is: $param1
    Write-Host param2 is: $param2
}
于 2013-06-11T11:54:29.977 回答
4

主要答案在版本 5 中仍然有效(根据评论,它可能在版本 2 中已经被破坏了一段时间)。

还有另一种选择:将 Position 添加到 ValueFromRemainingArgs 参数。

示例 CommandWrapper.ps1:

param(
    $namedOptional = "default",
    [Parameter(ValueFromRemainingArguments = $true, Position=1)]
    $cmdArgs
)

write-host "namedOptional: $namedOptional"
& cmd /c echo cmdArgs: @cmdArgs

样本输出:

>commandwrapper hello world
namedOptional: default
cmdArgs: hello world

这似乎遵循 PowerShell 从指定位置的第一个参数分配参数位置。

于 2019-05-23T18:42:45.287 回答