如何在 Powershell 中指定静态和动态位置参数?

Mic*_*ger 1 parameters powershell powershell-4.0 positional-parameter dynamicparameters

编辑

根据疯狂技术人员的建议,我已在 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
}
}
Run Code Online (Sandbox Code Playgroud)

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

测试位置:无法验证参数“Param1”的参数。参数“another”不属于 ValidateSet 属性指定的集合“some,list,of,values”。提供集合中的参数,然后重试该命令。在第 1 行 char:20 + Test-Positional 列出了另一个 + ~~~~~~~ + CategoryInfo : InvalidData: (:) [Test-Positional], ParameterBindingValidationException + ExcellentQualifiedErrorId : ParameterArgumentValidationError,Test-Positional

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

难道静态参数和动态参数都不可能都是位置参数吗?或者我在这里遗漏了一些明显的东西?

The*_*ian 5

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

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

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

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