给定此函数和调用:
function Foo($bar) {
Write-Host "bar=$bar, other args = $args"
}
Foo -b baz -quux quuux
Powershell会将-b
参数视为$bar
参数的别名并打印
bar=baz, other args = -quux quuux
我不希望它这样做!我的函数需要使用命名参数和任意附加参数;如果其中一个任意参数为-b
,我不希望将其分配给$bar
。也就是说,我希望它打印出来:
bar=, other args = -b baz -quux quuux
我可以抑制powershell的默认参数别名吗?
我正在使用powershell 2.0
答案 0 :(得分:2)
您可以通过引用解析器来阻止解析器将-b解释为参数别名:
function Foo($bar) {
Write-Host "bar=$bar, other args = $args"
}
Foo '-b' baz -quux quuux
bar=-b, other args = baz -quux quuux
答案 1 :(得分:2)
AFAIK,你无法双管齐下。您可以使用展示此处所示行为的“基本”函数,也可以使用带有命名参数的高级函数,该函数将严格验证参数名称。
“任意参数”变得非常非常丑陋,出于多种原因(其中一些涉及代码安全性 - 你最终会执行未知的任意代码吗?)应该避免恕我直言。
使Foo
成为高级函数,并使“任意”参数成为Objects
的集合,这是可选的。
function Foo {
[cmdletBinding()]
param (
[Parameter(Mandatory=$True)]
[string]$bar,
[Parameter(Mandatory=$False)]
[object[]]$args
)
Write-Output "bar=$bar";
# Test for $args here and process each item in it
}
答案 2 :(得分:2)
PowerShell无法禁用对参数的明确前缀匹配的支持。
虽然有各种权衡,但有一些选择。
选项1 - 自己解析参数:
function foo {
param()
# $args has all of the parameters and arguments
}
这对你来说更难写,但解决了你希望解决的问题,因为你将完全拥有参数/参数绑定。
另一个缺点是参数没有标签完成,至少在TabExpansion或TabExpansion2中没有一些额外的相应帮助(例如使用像TabExpansion ++或PowerTab这样的模块)。
请注意,在此示例中,即使您具有“来自剩余参数的值”的参数,也不希望cmdlet绑定,因为cmdlet绑定将添加公共参数,如果使用明确的前缀,这些参数将被绑定。 / p>
选项2 - 要求来电者做一些不同的事情
有几个具有类似问题的cmdlet,例如Invoke-Command或Get-Command。两者都接受一组参数。用户必须引用参数:
icm { param($a,$b) $b } -ArgumentList '-b','hello'
这些cmdlet使用-ArgumentList,因为它们必须接受可能与cmdlet参数冲突的任意参数。
如果您的问题受到更多限制,可能还有另一种选择,但它需要一些不常用的语法,并且仍然会遇到一些参数问题。一个例子:
function foo
{
param([Parameter(ValueFromRemainingArguments=$true)]$ArgumentList)
$ArgumentList
}
foo -- -A 1 -Ar 2 -Arg 3
特殊标记' - '告诉PowerShell后面的所有内容是一个参数。这样,看起来像参数的参数被视为参数。
如果来电者忘记' - ',这种做法可能会让人感到困惑。