如何设置参数依赖
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
}
参数规则:
- 至少应提供一个
Param#
(Param1
、Param2
或 Param3
)参数
- 只能提供一个
Param#
(Param1
、Param2
或Param3
)参数
- 开关(
Switch1
和 Switch2
)是可选的,只能通过 Param1
或 Param2
参数提供(一个或两个)
意味着以下命令会产生错误:
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'
这些匹配 参数集 Param1
和 Param1Switch
。它与其他参数集匹配,因为其他两个开关是可选的。但是,由于您指定了 DefaultParameterSetName='Param1'
,因此默认情况下 Param1
获胜。
在第二个参数集测试中:
Test-ParamSet -Param2 'Test'
同样,这些匹配 参数集 Param2
和 Param2Switch
。但是由于没有为 "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 选项,并且可以使用开关处理特殊情况。
到目前为止,我或多或少地避免在我的 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
}
参数规则:
- 至少应提供一个
Param#
(Param1
、Param2
或Param3
)参数 - 只能提供一个
Param#
(Param1
、Param2
或Param3
)参数 - 开关(
Switch1
和Switch2
)是可选的,只能通过Param1
或Param2
参数提供(一个或两个)
意味着以下命令会产生错误:
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'
这些匹配 参数集 Param1
和 Param1Switch
。它与其他参数集匹配,因为其他两个开关是可选的。但是,由于您指定了 DefaultParameterSetName='Param1'
,因此默认情况下 Param1
获胜。
在第二个参数集测试中:
Test-ParamSet -Param2 'Test'
同样,这些匹配 参数集 Param2
和 Param2Switch
。但是由于没有为 "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 选项,并且可以使用开关处理特殊情况。