我可以抑制参数别名吗?

时间:2014-02-12 13:52:16

标签: powershell powershell-v2.0

给定此函数和调用:

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

3 个答案:

答案 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后面的所有内容是一个参数。这样,看起来像参数的参数被视为参数。

如果来电者忘记' - ',这种做法可能会让人感到困惑。