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
CodePudding user response:
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 setD
is unambiguously implied.If either
-WidthReset
or-HeightReset
is present, parameter setC
orB
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).