0

到目前为止,我或多或少地避免在我的 PowerShell 脚本中使用参数集,因为我发现它们非常冗长且难以实现复杂的依赖项。
StackOverflow 上有几个类似的问题和答案,但我可以找到适合我情况的可接受的解决方案或解决方法。实际的脚本更加复杂,但这是我卡住了:

Function Test-ParamSet {
    [CmdletBinding(DefaultParameterSetName='Param1')][OutputType([Object[]])]Param (

        [Parameter(ParameterSetName = 'Param1', Mandatory = $True)]
        [Parameter(ParameterSetName = 'Param1Switch', Mandatory = $True)]
        $Param1,

        [Parameter(ParameterSetName = 'Param2', Mandatory = $True)]
        [Parameter(ParameterSetName = 'Param2Switch', Mandatory = $True)]
        $Param2,

        [Parameter(ParameterSetName = 'Param3', Mandatory = $True)]
        $Param3,

        [Parameter(ParameterSetName = 'Param1Switch')]
        [Parameter(ParameterSetName = 'Param2Switch')]
        [Switch]$Switch1,

        [Parameter(ParameterSetName = 'Param1Switch')]
        [Parameter(ParameterSetName = 'Param2Switch')]
        [Switch]$Switch2
    )
    Write-Host $PsCmdlet.ParameterSetName
}

参数规则:

  • 至少应提供一个Param#( Param1,Param2或) 参数Param3
  • 只能提供一个Param#( Param1,Param2Param3) 参数
  • 开关 (Switch1Switch2) 是可选的,只能与Param1orParam2参数一起提供(一个或两个)

这意味着以下命令应该会产生错误:

Test-ParamSet
Test-ParamSet -Param3 'Test' -Switch1

并且应该接受以下命令:

Test-ParamSet -Param1 'Test'
Test-ParamSet -Param1 'Test' -Switch1
Test-ParamSet -Param2 'Test' -Switch1 -Switch2

问题在于以下命令:

Test-ParamSet -Param2 'Test'

它会产生一个意外错误:

Test-ParamSet : Parameter set cannot be resolved using the specified named parameters. 
One or more parameters issued cannot be used together or an insufficient number of parameters were provided.
At line:1 char:1
+ Test-ParamSet -Param2 'Test'
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : InvalidArgument: (:) [Test-ParamSet], ParameterBindingException
+ FullyQualifiedErrorId : AmbiguousParameterSet,Test-ParamSet

我想这与@mklement0如何更改参数的抛出消息中提到的这个 github 问题有关?.

但是如何使用参数集充分解决或解决此问题?

4

2 回答 2

1

添加到@SagePourpre 和@iRon 评论并添加可能相关的额外信息。

在这种情况下,错误是正确的,问题是您同时匹配2 个参数集-->没有指定默认参数集

例如第一个参数集测试:

Test-ParamSet -Param1 'Test'

这些匹配参数集。它与其他参数集匹配,因为其他两个开关是可选的。但是,由于您默认指定then获胜。Param1Param1SwitchDefaultParameterSetName='Param1'Param1

在第二个参数集测试中:

Test-ParamSet -Param2 'Test'

同样,这些匹配参数集. 但是由于没有指定默认参数集来“赢得”分歧,并且开关是可选的(以匹配第二个参数集),因此会引发错误。Param2Param2Switch

解决方案是简化集合名称,使其一次只能匹配一个集合。特别是当您处理可选参数时:

Function Test-ParamSet {
    [CmdletBinding(DefaultParameterSetName='Param1')][OutputType([Object[]])]Param (

        [Parameter(ParameterSetName = 'Param1', Mandatory = $True)]
        $Param1,

        [Parameter(ParameterSetName = 'Param2', Mandatory = $True)]
        $Param2,

        [Parameter(ParameterSetName = 'Param3', Mandatory = $True)]
        $Param3,

        [Parameter(ParameterSetName = 'Param1')]
        [Parameter(ParameterSetName = 'Param2')]
        [Switch]$Switch1,

        [Parameter(ParameterSetName = 'Param1')]
        [Parameter(ParameterSetName = 'Param2')]
        [Switch]$Switch2
    )
    Write-Host $PsCmdlet.ParameterSetName
}

另一种方法是将开关指定为强制参数集名称为特定开关。例如:

Function Test-ParamSet {
    [CmdletBinding(DefaultParameterSetName='Param1')][OutputType([Object[]])]Param (

        [Parameter(ParameterSetName = 'Param1', Mandatory = $True)]
        [Parameter(ParameterSetName = 'Param1Switch', Mandatory = $True)]
        $Param1,

        [Parameter(ParameterSetName = 'Param2', Mandatory = $True)]
        [Parameter(ParameterSetName = 'Param2Switch', Mandatory = $True)]
        $Param2,

        [Parameter(ParameterSetName = 'Param3', Mandatory = $True)]
        $Param3,

        [Parameter(ParameterSetName = 'Param1Switch', Mandatory = $True)]
        [Parameter(ParameterSetName = 'Param2Switch', Mandatory = $True)]
        [Parameter(ParameterSetName = 'Param1And2Switch', Mandatory = $True)]     
        [Switch]$Switch1,

        [Parameter(ParameterSetName = 'Param1Switch', Mandatory = $True)]
        [Parameter(ParameterSetName = 'Param2Switch', Mandatory = $True)]
        [Parameter(ParameterSetName = 'Param1And2Switch', Mandatory = $True)]     
        [Switch]$Switch2
    )
    Write-Host $PsCmdlet.ParameterSetName
}

这样,对于所有可能的解决方案,您只有一个 ParameterSet 选项,并且可以使用开关处理特殊情况。

于 2019-12-09T16:20:48.867 回答
1

开关参数应该是 Param1 和 Param2 命名集的成员。然后,可以从$Param1&$Param2定义中删除 Param1Switch 和 Param2Switch 命名集。

这是最终结果。

Function Test-ParamSet {
    [CmdletBinding(DefaultParameterSetName='Param1')][OutputType([Object[]])]Param (

        [Parameter(ParameterSetName = 'Param1', Mandatory = $True)]
        $Param1,

        [Parameter(ParameterSetName = 'Param2', Mandatory = $True)]
        $Param2,

        [Parameter(ParameterSetName = 'Param3', Mandatory = $True)]
        $Param3,

        [Parameter(ParameterSetName = 'Param1')]
        [Parameter(ParameterSetName = 'Param2')]
        [Switch]$Switch1,

        [Parameter(ParameterSetName = 'Param1')]
        [Parameter(ParameterSetName = 'Param2')]
        [Switch]$Switch2
    )
    Write-Host $PsCmdlet.ParameterSetName
}
于 2019-12-09T15:42:33.383 回答