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