Powershell非定位,可选参数

Fop*_*ush 17 powershell scripting arguments

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

.\{script name} [options] PATH
Run Code Online (Sandbox Code Playgroud)

选项是任意数量的可选参数 - 按照'-v'的方式考虑详细.PATH参数将只是最后传递的参数,并且是必需的.可以在没有选项和只有一个参数的情况下调用脚本,并且该参数将被假定为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"
Run Code Online (Sandbox Code Playgroud)

当这样调用时:

.\param-test.ps1 firstValue secondValue
Run Code Online (Sandbox Code Playgroud)

脚本输出:

first arg is firstValue
second arg is secondValue
third arg is False
remaining:
Run Code Online (Sandbox Code Playgroud)

试图创建的行为将使两个参数都通过可选参数落在最后的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"
Run Code Online (Sandbox Code Playgroud)

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

.\param-test.ps1 firstValue secondValue
Run Code Online (Sandbox Code Playgroud)

输出如下:

first arg is firstValue
second arg is
third arg is False
remaining: secondValue
Run Code Online (Sandbox Code Playgroud)

第一个强制性参数被分配,剩下的一切都完全消失了.

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

lat*_*kin 29

这个怎么样?

function test
{
   param(
      [string] $One,

      [string] $Two,

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

   "One = [$one]  Two = [$two]  Three = [$three]"
}
Run Code Online (Sandbox Code Playgroud)

One并且Two是可选的,并且只能通过名称指定. 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]
Run Code Online (Sandbox Code Playgroud)

这将失败:

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
Run Code Online (Sandbox Code Playgroud)

这并不强制您的强制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]"
}
Run Code Online (Sandbox Code Playgroud)

现在像这样的工作:

test -one 'foo' 'bar' 'baz'
  One = [foo]  Two = []  Three = [bar baz]
Run Code Online (Sandbox Code Playgroud)

甚至

test 'foo' -one 'bar' 'baz'
    One = [bar]  Two = []  Three = [foo baz]
Run Code Online (Sandbox Code Playgroud)

  • 正是我需要的。我没有想到我可以使用 Position=0 的强制参数作为 _last_ 参数。 (2认同)