简体   繁体   English

如何设置参数依赖

[英]How do set parameter dependencies

Up till now I was more or less avoiding parameter-sets in my PowerShell script as I find them very verbose and quiet difficult to implement for complex dependencies.到目前为止,我或多或少地避免了我的 PowerShell 脚本中的参数集,因为我发现它们非常冗长且安静,难以实现复杂的依赖项。
There are several similar questions and answers at StackOverflow but I can find an acceptable solution or workaround to my situation. StackOverflow 上有几个类似的问题和答案,但我可以找到适合我的情况的可接受的解决方案或解决方法。 The actual script is even more complex but this is were I get stuck:实际的脚本更复杂,但这是我卡住了:

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
}

Parameter rules:参数规则:

  • At least one Param# ( Param1 , Param2 or Param3 ) parameter should be supplied至少应提供一个Param#Param1Param2Param3 )参数
  • Only one Param# ( Param1 , Param2 or Param3 ) parameter can be supplied只能提供一个Param#Param1Param2Param3 )参数
  • The switches ( Switch1 and Switch2 ) are optional can only be supplied (either one or both) with the Param1 or Param2 parameter开关( Switch1Switch2 )是可选的,只能与Param1Param2参数一起提供(一个或两个)

Meaning the following commands should produce an error:这意味着以下命令应该会产生错误:

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

And the following commands should be accepted:并且应该接受以下命令:

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

The problem is with the following command:问题在于以下命令:

Test-ParamSet -Param2 'Test'

It generates an unexpected error:它会产生一个意外错误:

 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

I guess this is related to this github issue mentioned by @mklement0 in How do you change a parameter's throw message?我想这与@mklement0How do you change a parameter's throw message 中提到的这个 github 问题有关 . .

But how can I adequately resolve or workaround this using parameter-sets?但是如何使用参数集充分解决或解决此问题?

The switch parameters should be member of the Param1 and Param2 naming set.开关参数应该是 Param1 和 Param2 命名集的成员。 Then, the Param1Switch & Param2Switch naming set can be removed from $Param1 & $Param2 definition.然后,Param1Switch & Param2Switch 命名集可以从$Param1 & $Param2定义中删除。

Here's the end result.这是最终结果。

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
}

To add to @SagePourpre and @iRon comment and add what may be relevant extra information.添加到@SagePourpre 和@iRon 评论并添加可能相关的额外信息。

In this instance, the error is correct, and the issue is that you are matching 2 parameter sets at the same time --> with no default parameter set specified .在这种情况下,错误是正确的,问题是您同时匹配2 个参数集-->没有指定默认参数集

eg First parameter set test:例如第一个参数集测试:

Test-ParamSet -Param1 'Test'

These match both Parameter sets Param1 and Param1Switch .这些比赛该参数设定Param1Param1Switch It matches the other parameter set because the other two switches are optional.它匹配其他参数集,因为其他两个开关是可选的。 But, since you specify the DefaultParameterSetName='Param1' then Param1 wins by default.但是,由于您指定了DefaultParameterSetName='Param1'则默认情况下Param1获胜。

In the second parameter set test:在第二个参数集测试中:

Test-ParamSet -Param2 'Test'

Again, these match both Parameter sets Param2 and Param2Switch .同样,这些同时匹配参数设置Param2Param2Switch But since there is no Default Parameter Set specified to "win" the disagreement, and the switches are optional (to match the second parameter set), it throws the error.但是由于没有指定默认参数集来“赢得”分歧,并且开关是可选的(以匹配第二个参数集),因此会引发错误。

The solution is to simplify the set names so that it only can match one set at a time.解决方案是简化集合名称,使其一次只能匹配一个集合。 Especially when you deal with optional parameters:特别是当您处理可选参数时:

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
}

The Other way of doing it is to specify the switches as mandatory to force the parameter set name to a specific one.另一种方法是将开关指定为强制参数集名称为特定的。 eg:例如:

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
}

This way you only have one ParameterSet option for all possible solutions, and can handle special cases with switches.这样,对于所有可能的解决方案,您只有一个 ParameterSet 选项,并且可以使用开关处理特殊情况。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM