如何设置参数依赖

How do set parameter dependencies

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

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
}

参数规则:

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

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

我猜这与 this github issue mentioned by @mklement0 in 有关。

但是我怎样才能使用参数集充分解决或解决这个问题?

开关参数应该是 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
}

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

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

例如第一个参数集测试:

Test-ParamSet -Param1 'Test'

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

在第二个参数集测试中:

Test-ParamSet -Param2 'Test'

同样,这些匹配 参数集 Param2Param2Switch。但是由于没有为 "win" 指定默认参数集,因此不一致, 开关是可选的(以匹配第二个参数集),它会抛出错误。

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

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 选项,并且可以使用开关处理特殊情况。