I've been trying to get multiple sets of mutual exclusions to work. I want "Width" mutually exclusive to "WidthReset" and "Height" to be mutually exclusive with "HeightReset".
Help for the cmdlet shows:
Get-ArgTest [-Width <int>] [-Height <int>] [<CommonParameters>]
Get-ArgTest [-Width <int>] [-HeightReset] [<CommonParameters>]
Get-ArgTest [-Height <int>] [-WidthReset] [<CommonParameters>]
Get-ArgTest [-WidthReset] [-HeightReset] [<CommonParameters>]
See the following code.
Everything works, but Get-ArgTest -WidthReset seems to be ambiguous.
Why is this one case is ambiguous? Other, symmetrical cases are not flagged as ambiguous.
How can I resolve the ambiguity?
Changing the DefaultParameterSetName to B or C changes which case is ambiguous.
That indicates to me that it should work.
##########################################
# This cmdlet *should* accept
# [-Width | -WidthReset] [-Height | -HeightReset]
##########################################
function Get-ArgTest
{
[CmdletBinding(DefaultParameterSetName = 'A')]
param(
[Parameter(ParameterSetName='A')]
[Parameter(ParameterSetName='B')]
[int] $Width,
[Parameter(ParameterSetName='C')]
[Parameter(ParameterSetName='A')]
[int] $Height,
[Parameter(ParameterSetName='C')]
[Parameter(ParameterSetName='D')]
[switch] $WidthReset,
[Parameter(ParameterSetName='B')]
[Parameter(ParameterSetName='D')]
[switch] $HeightReset
)
Write-Output "HELLO, Width=$Width, Height=$Height, WidthReset=$WidthReset, HeightReset=$HeightReset"
}
##########################################
# Tests
##########################################
# First, display HELP
Get-ArgTest -?
####
## Try each combination
# First, just the values
Get-ArgTest
Get-ArgTest -Width 2
Get-ArgTest -Height 4
Get-ArgTest -Width 2 -Height 4
# Values and the opposite reset
Get-ArgTest -Width 2 -HeightReset
Get-ArgTest -Height 4 -WidthReset
# The Resets
Get-ArgTest -WidthReset -HeightReset
Get-ArgTest -WidthReset -HeightReset:$False
Get-ArgTest -WidthReset:$False -HeightReset:$True
# I cannot get the following cases to work :-(
Get-ArgTest -WidthReset
Get-ArgTest -HeightReset
To avoid the ambiguity, make -WidthReset and -HeightReset mandatory in your D parameter set:
function Get-ArgTest
{
[CmdletBinding(DefaultParameterSetName = 'A')]
param(
[Parameter(ParameterSetName='A')]
[Parameter(ParameterSetName='B')]
[int] $Width,
[Parameter(ParameterSetName='C')]
[Parameter(ParameterSetName='A')]
[int] $Height,
[Parameter(ParameterSetName='C')]
[Parameter(ParameterSetName='D', Mandatory)]
[switch] $WidthReset,
[Parameter(ParameterSetName='B')]
[Parameter(ParameterSetName='D', Mandatory)]
[switch] $HeightReset
)
Write-Output "HELLO, Width=$Width, Height=$Height, WidthReset=$WidthReset, HeightReset=$HeightReset"
}
This results in the following syntax diagram (Get-Command -Syntax Get-ArgTest):
Get-ArgTest [-Width <int>] [-Height <int>] [<CommonParameters>]
Get-ArgTest [-Width <int>] [-HeightReset] [<CommonParameters>]
Get-ArgTest [-Height <int>] [-WidthReset] [<CommonParameters>]
Get-ArgTest -WidthReset -HeightReset [<CommonParameters>]
As a result:
If both -WidthReset and -HeightReset are present, parameter set D is unambiguously implied.
If either -WidthReset or -HeightReset is present, parameter set C or B is unambiguously implied.
As for what you tried:
With your original function definition, the following calls are ambiguous:
Get-ArgTest -WidthReset
Get-ArgTest -HeightReset
because the former matches both parameter set C and D,
and the latter both B and D,
and none of them is the default parameter set (which would act as the tie-breaker).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With