【问题标题】:PowerShell script not assigning named parameter correctly [closed]PowerShell脚本未正确分配命名参数[关闭]
【发布时间】:2020-02-03 05:04:55
【问题描述】:

我有一个以以下块开头的脚本

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?

【问题讨论】:

  • @darxsys 您实际上是如何调用脚本的?请显示您正在运行的确切命令。
  • 虽然它可能很旧,但我完全同意@mklement0 应该重新打开它(并且我已经投了这样的票)。如果我没有看到这一点,它还只是帮助我防止了我以后工作中可能出现的更大问题。

标签: powershell scripting


【解决方案1】:

虽然 通常不建议将参数命名为 $args,正如 Ansgar Wiechers 指出的那样,因为 $args 通常是 automatic variable,但您的解决方案应该仍然可以在 原则,至少在最近的 PowerShell 版本中是这样。

但是,正如 TessellatingHeckler 指出的那样,使用 -ou 调用会导致错误,因为 - 由于使用了参数属性 ([Parameter(...)]) - 您的函数是隐式支持 common parameters such as -OutVariable and -OutBufferadvanced function,@ 987654331@ 尝试根据名称-前缀匹配进行绑定,但由于歧义而失败。
然而,更大的问题是,您因此不能按原样传递(未声明的)参数名,这些参数名是高级函数中常用参数名的前缀

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

次优解决方法

  • 将所有传递参数放在命令行的末尾在它们之前--,这个特殊参数表示所有剩余的标记将被解释为 位置 参数,即使它们看起来像参数名称。
# Everything after -- (which itself will be removed), is passed
# through as a *positional* argument (which a ValueFromRemainingArguments
# parameter would collect).
Foo -c 16.0 -- -n -cc -ou name 

注意:您也可以引用单个标记以防止将它们解释为参数名称(例如,Foo -n -cc '-ou' name -c 16.0),但这需要您记住所有常用参数的名称并应用引用根据需要。


如果不需要高级函数的特性,更好的解决方法是使用简单函数

  • 使用自动$Args 变量来访问所有未绑定到已声明参数的参数(不要将其声明为参数)。
  • 但是,这要求您既不使用任何参数属性也不使用[CmdletBinding()] 属性,以防止函数成为高级 - 请参阅about_Functions_Advanced
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]

【讨论】:

  • 哇,我不知道--那样,很有趣,
猜你喜欢
  • 2021-05-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-31
  • 1970-01-01
  • 2019-08-03
  • 1970-01-01
  • 2016-05-21
相关资源
最近更新 更多