20

我正在尝试创建一个 powershell (2.0) 脚本,该脚本将接受遵循此基本模式的参数:

.\{script name} [options] PATH

其中 options 是任意数量的可选参数 - 考虑详细的“-v”行。PATH 参数将只是最后传入的任何参数,并且是强制性的。可以在没有选项且只有一个参数的情况下调用脚本,并且该参数将被假定为路径。我无法设置仅包含可选参数但也是非位置参数的参数列表。

这个快速脚本演示了我遇到的问题:

#param test script
Param(
    $firstArg,
    $secondArg,
    [switch]$thirdArg,
    [Parameter(ValueFromRemainingArguments = $true)]
    $remainingArgs)

write-host "first arg is $firstArg"
write-host "second arg is $secondArg"
write-host "third arg is $thirdArg"
write-host "remaining: $remainingArgs"

当这样调用时:

.\param-test.ps1 firstValue secondValue

脚本输出:

first arg is firstValue
second arg is secondValue
third arg is False
remaining:

试图创建的行为将使两个参数都落在可选参数中并最终出现在 remainingArgs 变量中。

这个问题/答案很有帮助地提供了一种实现所需行为的方法,但它似乎只有在至少有一个强制参数时才有效,并且只有当它出现所有其他参数之前。

我可以通过强制 firstArg 并将位置指定为 0 来演示此行为:

#param test script
Param(
    [Parameter(Mandatory=$true, Position = 0)]
    $firstArg,
    $secondArg,
    [switch]$thirdArg,
    [Parameter(ValueFromRemainingArguments = $true)]
    $remainingArgs)

    write-host "first arg is $firstArg"
    write-host "second arg is $secondArg"
    write-host "third arg is $thirdArg"
    write-host "remaining: $remainingArgs"

使用与以前相同的输入运行:

.\param-test.ps1 firstValue secondValue

输出如下:

first arg is firstValue
second arg is
third arg is False
remaining: secondValue

第一个强制参数被赋值,剩下的所有东西都一直掉下去。

问题是:如何设置一个参数列表,使所有参数都是可选的,并且它们都不是位置的?

4

1 回答 1

36

这个怎么样?

function test
{
   param(
      [string] $One,

      [string] $Two,

      [Parameter(Mandatory = $true, Position = 0)]
      [string] $Three
   )

   "One = [$one]  Two = [$two]  Three = [$three]"
}

OneTwo是可选的,只能按名称指定。 Three是强制性的,并且可以不提供名称。

这些工作:

test 'foo'
    One = []  Two = []  Three = [foo]
test -One 'foo' 'bar'
    One = [foo]  Two = []  Three = [bar]
test 'foo' -Two 'bar'
    One = []  Two = [bar]  Three = [foo]

这将失败:

test 'foo' 'bar'
test : A positional parameter cannot be found that accepts argument 'bar'.
At line:1 char:1
+ test 'foo' 'bar'
+ ~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (:) [test], ParameterBindingException
    + FullyQualifiedErrorId : PositionalParameterNotFound,test

这并不强制您的强制 arg 放在最后,或者它没有被命名。但它允许您想要的基本使用模式。

它也不允许在$Three. 这可能是你想要的。但是,如果您想将多个未命名的参数视为 的一部分$Three,则添加该ValueFromRemainingArguments属性。

function test
{
   param(
      [string] $One,

      [string] $Two,

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

   "One = [$one]  Two = [$two]  Three = [$three]"
}

现在这样的工作:

test -one 'foo' 'bar' 'baz'
  One = [foo]  Two = []  Three = [bar baz]

甚至

test 'foo' -one 'bar' 'baz'
    One = [bar]  Two = []  Three = [foo baz]
于 2012-09-11T20:43:39.657 回答