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

时间:2017-07-10 21:12:34

标签: powershell parameters powershell-v4.0 positional-parameter dynamicparameters

修改

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

原始问题

我希望能够在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' 我收到错误:

  

Test-Positional:无法验证参数' Param1'的参数。该   争论"另一个"不属于集合" some,list,of,values"   由ValidateSet属性指定。提供一个参数   设置然后再次尝试该命令。在行:1 char:20   +测试 - 位置列表另一个如此   + ~~~~~~~       + CategoryInfo:InvalidData :( :) [Test-Positional],ParameterBindingValidationException       + FullyQualifiedErrorId:ParameterArgumentValidationError,Test-Positional

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

,我会收到同样的错误

是否不可能同时将静态和动态参数作为位置参数?或者我错过了一些明显的东西?

1 个答案:

答案 0 :(得分:4)

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

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

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

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