PowerShell是否忽略了脚本参数的声明位置?

时间:2016-10-24 12:33:44

标签: powershell

我处理的是一个旨在由第三方应用程序调用的脚本。应用程序将一堆参数传递给脚本,但在我的情况下只需要几个参数。所有参数都按位置传递。所以我只在Param()中指定了所需的参数:

Param(
    [Parameter(Position=2)][ValidateNotNullOrEmpty()]
        [string]$thirdParam=$(throw "Third parameter isn't specified"),
    [Parameter(Position=3)][ValidateNotNullOrEmpty()]
        [string]$fourthParam=$(throw "Fourth parameter isn't specified"),
    [Parameter(ValueFromRemainingArguments=$true)]
        [String[]]$redundantParams
)
$thirdParam
$fourthParam

这是脚本及其输出的调用:

> .\Test1.ps1 1 2 3 4 5
1
2

看起来PowerShell会忽略Position参数的值,并将第一个和第二个传递的值分别绑定到$thirdParam$fourthParam。即使Position值大于传递的参数值的实际数量,它也不会导致错误,就好像它被忽略一样:

Param(
    [Parameter(Position=1)][ValidateNotNullOrEmpty()]
        [string]$secondParam=$(throw "Second parameter isn't specified"),
    [Parameter(Position=2)][ValidateNotNullOrEmpty()]
        [string]$thirdParam=$(throw "Third parameter isn't specified"),
    [Parameter(ValueFromRemainingArguments=$true)]
        [String[]]$redundantParams
)
$secondParam
$thirdParam

> .\Test1.ps1 1 2
1
2

在两种情况下都使用PowerShell v.4.0

> $PSVersionTable

Name                           Value
----                           -----
PSVersion                      4.0
WSManStackVersion              3.0
SerializationVersion           1.1.0.1
CLRVersion                     4.0.30319.18444
BuildVersion                   6.3.9600.18144
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0}
PSRemotingProtocolVersion      2.2

PowerShell为什么忽略Position参数?在上述情况下,是否可以PowerShell考虑Position值?

2 个答案:

答案 0 :(得分:2)

UnboundArguments

如果您的脚本接受未绑定的参数(即它未指定CmdletBinding),那么您可以访问绑定未绑定使用 $ MyInvocation 内置变量的参数:

$MyInvocation.BoundParameters
$MyInvocation.UnboundArguments

您可以省去整个param()块并使用$MyInvocation.UnboundArguments作为零索引数组来识别传递给脚本的位置参数:

$ThirdParam  = $MyInvocation.UnboundArguments[2]
$FourthParam = $MyInvocation.UnboundArguments[3]

请注意,如果你有一个param()块,那么传递给脚本的位置参数将绑定到这些参数,从而绑定到BoundParameters对象(又名 $ PSBoundParameters )。所有剩余的参数都会添加到UnboundArguments列表中。

param(
  $one,
  $two)

Write-Debug "PSBoundParameters: $($PSBoundParameters.GetType().Name)"
$PSBoundParameters.GetEnumerator() | Select Key,Value | Out-String

Write-Debug "MyInvocation.BoundParameters: $($MyInvocation.BoundParameters.GetType().Name)"
$MyInvocation.BoundParameters.GetEnumerator() | Select Key,Value | Out-String

Write-Debug "MyInvocation.UnboundArguments: $($MyInvocation.UnboundArguments.GetType().Name)"
$MyInvocation.UnboundArguments

答案 1 :(得分:2)

当您声明大于“0”的较低位置编号或大于“1”的数字之间不同时,较低位置编号的位置将声明为“0”,一旦最接近最大值的参数声明为“1”,则下一个更大用位置“2”声明,依此类推。 喜欢这张照片:

enter image description here

你的输出将是:

7
8