1

编辑

根据 The Mad Technician 的建议,我已在 PowerShell UserVoice 网站上为此提交了一份错误报告:https ://windowsserver.uservoice.com/forums/301869-powershell/suggestions/20034763-dynamic-parameters-and-positional-parameters -不要

原始问题

我希望能够在包含静态和动态参数的 PowerShell 函数中指定位置参数。例如我有

function Test-Positional{
[CmdletBinding(PositionalBinding=$false)]
param(
    [Parameter(Mandatory=$false,Position=3)][string]$Param4
)
dynamicparam {
    $paramDictionary = new-object -Type System.Management.Automation.RuntimeDefinedParameterDictionary

    $paramname1 = "Param1"
    $values1 = 'some','list','of','values' #would normally get these dynamically
    $attributes1 = new-object System.Management.Automation.ParameterAttribute
    $attributes1.ParameterSetName = "__AllParameterSets"
    $attributes1.Mandatory = $true
    $attributes1.Position = 0
    $attributeCollection1 = new-object -Type System.Collections.ObjectModel.Collection[System.Attribute]
    $attributeCollection1.Add($attributes1)
    $ValidateSet1 = new-object System.Management.Automation.ValidateSetAttribute($values1)
    $attributeCollection1.Add($ValidateSet1)
    $dynParam1 = new-object -Type System.Management.Automation.RuntimeDefinedParameter($paramname1, [string], $attributeCollection1)

    $paramname2 = "Param2"
    $values2 = 'another','list','like','before'
    $attributes2 = new-object System.Management.Automation.ParameterAttribute
    $attributes2.ParameterSetName = "__AllParameterSets"
    $attributes2.Mandatory = $true
    $attributes2.Position = 1
    $attributeCollection2 = new-object -Type System.Collections.ObjectModel.Collection[System.Attribute]
    $attributeCollection2.Add($attributes2)
    $ValidateSet2 = new-object System.Management.Automation.ValidateSetAttribute($values2)
    $attributeCollection2.Add($ValidateSet2)
    $dynParam2 = new-object -Type System.Management.Automation.RuntimeDefinedParameter($paramname2, [string], $attributeCollection2)

    $paramname3 = "Param3"
    $values3 = 'yet','another','list'
    $attributes3 = new-object System.Management.Automation.ParameterAttribute
    $attributes3.ParameterSetName = "__AllParameterSets"
    $attributes3.Mandatory = $true
    $attributes3.Position = 2
    $attributeCollection3 = new-object -Type System.Collections.ObjectModel.Collection[System.Attribute]
    $attributeCollection3.Add($attributes3)
    $ValidateSet3 = new-object System.Management.Automation.ValidateSetAttribute($values3)
    $attributeCollection3.Add($ValidateSet3)
    $dynParam3 = new-object -Type System.Management.Automation.RuntimeDefinedParameter($paramname3, [string], $attributeCollection3)

    $paramDictionary.Add($paramname1, $dynParam1)
    $paramDictionary.Add($paramname2, $dynParam2)
    $paramDictionary.Add($paramname3, $dynParam3)
    return $paramDictionary
}

process{
   $PSBoundParameters.Param1
   $PSBoundParameters.Param2
   $PSBoundParameters.Param3
   $PSBoundParameters.Param4
}
}

但如果我运行PS C:\Windows\System32\inetsrv> Test-Positional 'list' 'another' 'yet' 'so' 我会得到错误:

测试位置:无法验证参数“Param1”上的参数。参数“another”不属于 ValidateSet 属性指定的集合“some,list,of,values”。提供集合中的参数,然后再次尝试该命令。在 line:1 char:20 + Test-Positional list another so + ~~~~~~~ + CategoryInfo : InvalidData: (:) [Test-Positional], ParameterBindingValidationException + FullyQualifiedErrorId : ParameterArgumentValidationError,Test-Positional

如果我从静态参数 ($param4) 中删除属性,它不会抛出这个Position=3,这很好,除非我不能将它用作位置参数,我必须直接命名它。如果我保留Position=3并删除,我会得到同样的错误PositionalBinding=$false

静态和动态参数是不是不可能同时是位置参数?还是我在这里遗漏了一些明显的东西?

4

1 回答 1

4

位置与相同类型的参数相关。所以静态参数会尊重其他静态参数的位置,动态参数会尊重其他动态参数的位置,但是静态参数会先消耗参数,动态参数会消耗剩下的。我知道的唯一例外是如果您使用 的参数属性ValueFromRemainingArguments=$true,这会强制该特定参数成为最后一个参数。因此,如果您真的只有 1 个静态参数想要在动态参数之后出现,您可以设置ValueFromRemainingArguments=$true它,它会按照您的意愿运行。如果您有其他静态参数,无论您指定的位置是否晚于动态参数的位置,它们仍将位于动态参数之前。

在我看来,您发现了一个错误,我鼓励您在 PowerShell UserVoice 网站上为此提交错误:https ://windowsserver.uservoice.com/forums/301869-powershell

在我看来,他们应该更新文档以说明在 stat 参数定位之后评估动态参数定位并在Get-Help针对函数/脚本运行时更正语法部分,或者相应地更新行为以便在动态和静态中都尊重位置参数。我自己更喜欢后者,但这可能涉及不可行的引擎更改。

如果您确实创建了一个错误,请提供一个指向它的链接,以便其他人可以找到它并对其进行投票(以便它获得关注并得到修复!)。

于 2017-07-10T22:52:10.537 回答