我正在编写一个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
如果我使用命名的param运行,一切都很棒:
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
添加到参数中,但这会产生相同的结果。
有没有办法实现这个目标?
也许是一个不同的参数方案?
答案 0 :(得分:8)
默认情况下,所有函数参数都是位置参数。 Windows PowerShell按照在函数中声明参数的顺序为参数分配位置编号。要禁用此功能,请将PositionalBinding
属性的CmdletBinding
参数值设置为$False
。
看看at How to disable positional parameter binding in PowerShell
function Test-PositionalBinding
{
[CmdletBinding(PositionalBinding=$false)]
param(
$param1,$param2
)
Write-Host param1 is: $param1
Write-Host param2 is: $param2
}
答案 1 :(得分:0)
主要答案在版本5中仍然有效(根据评论,它可能在版本2中已经破解了一段时间)。
还有另一种选择:将位置添加到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从第一个参数分配了具有指定位置的参数位置之后进行的。