修改
根据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
是否不可能同时将静态和动态参数作为位置参数?或者我错过了一些明显的东西?
答案 0 :(得分:4)
位置与相同类型的参数相关。因此静态参数将尊重其他静态参数的位置,动态参数将尊重其他动态参数的位置,但静态参数将首先使用参数,并且动态参数将消耗剩下的任何内容。我所知道的唯一例外是,如果你使用ValueFromRemainingArguments=$true
的参数属性,它会强制该特定参数成为最后一个参数。因此,如果您真的只有1个静态参数,您想要在动态参数之后,您可以设置ValueFromRemainingArguments=$true
,它将按您的意愿运行。如果您有其他静态参数,它们仍将位于动态参数之前,无论您是否指定比动态参数更晚的位置。
在我看来,您发现了一个错误,我建议您在PowerShell UserVoice网站上为此提交错误:https://windowsserver.uservoice.com/forums/301869-powershell
在我看来,他们应该更新文档以声明在stat参数定位后评估动态参数定位,并在针对函数/脚本运行Get-Help
时更正语法部分,或者相应地更新行为以便在动态和静态参数中都遵守位置。我自己更喜欢后者,但这可能涉及不可行的发动机变化。
如果您确实创建了一个错误,请提供一个链接,以便其他人可以找到并投票(以便获得关注,并得到修复!)。