PowerShell脚本未正确分配命名参数

时间:2018-05-04 22:45:49

标签: powershell scripting

我有一个以下面的块

开头的脚本
Param(
    [string] $c,

    [Parameter(ValueFromRemainingArguments=$true)]
    [string] $args
)

当我调用此脚本并指定-n -cc -ou name -c 16.0.时,似乎只需要整个命令行并将其填入$c。如果我这样做

[Parameter(Position=0, ValueFromRemainingArguments=$true)]
[string] $args

然后它实际上并没有选择-c 16.0.并将其放入$c,而只是将所有内容都填入$args。为什么呢?

所以我想要的是希望简单。可以指定-c,但不必指定。还可以指定一堆其他参数,但不必为那些我只想在一个字符串中收集它们。如果指定了-c,我希望将其放入$c,但不在$args中。如果未指定-c,则$c变量应为空。怎么实现呢?

这是我尝试使用的答案,但对我来说不起作用:

How do I force declared parameters to require explicit naming?

1 个答案:

答案 0 :(得分:3)

虽然命名参数$args通常是不明智的,正如Ansgar Wiechers指出的那样,因为$args通常是automatic variable,所以你的解决方案仍应在中工作原则,至少在最近的PowerShell版本中。

但是,正如TessellatingHeckler指出的那样,-ou会导致错误,因为 - 由于使用了参数属性([Parameter(...)]) - 您的函数是高级函数隐式支持common parameters such as -OutVariable and -OutBuffer-ou尝试基于名称前缀匹配绑定到,但由于歧义而失败。
但是,更大的问题是因此您不能使用作为通用参数名称前缀的参数名称。

(使用高级功能的另一个副作用是自动$Args变量填充,因为您只能传递绑定到声明的参数参数高级函数。)

要解决该问题,请使用简单函数(但是,这会阻止您使用参数属性):

  • 使用自动 $Args变量访问未绑定到声明参数的所有参数,
  • 但是,
  • 要求您既不使用任何参数属性,也不要求使用[CmdletBinding()]属性:
function Foo {
  # Don't use [CmdletBinding()] or [Parameter(...)] attributes.
  # Only then will the automatic $Args variable work.
  Param(
      [string] $c
  )

  "`$c: [$c]"

  # Use the automatic $Args variable, which collects all arguments
  # that did not bind to declared parameters in an array.
  $argsAsString = [string] $Args
  "`$Args: [$argsAsString]"
}

Foo -n -cc -ou name -c 16.0.

以上产量:

$c: [16.0.]
$args: [-n -cc -ou name]