Question:
I’m writing a function for which two parameters should be exclusive and optional.
Here are valid inputs:
1 2 3 4 5 6 7 8 |
new-event -Title sometitle -Text sometext -TimestampHappened 1234567 -SomeOtherOptionalParam somestring new-event -Title sometitle -Text sometext -DateHappened (get-date) -SomeOtherOptionalParam somestring new-event -Title sometitle -Text sometext -SomeOtherOptionalParam somestring new-event -Title sometitle -Text sometext |
Here is an invalid input:
1 2 |
new-event -Title sometitle -Text sometext -DateHappened (get-date) -TimestampHappened 1234567 -SomeOtherOptionalParam somestring |
Here is my code so far:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
[CmdletBinding()] # Most parameters belong to Default, New-Event:ByDate and New-Event:ByTimestamp parameter sets param ( [Parameter( Position=0, Mandatory=$True, ParameterSetName="Default" )] [Parameter( Position=0, Mandatory=$True, ParameterSetName="New-Event:ByDate" )] [Parameter( Position=0, Mandatory=$True, ParameterSetName="New-Event:ByTimestamp" )] [ValidateNotNullOrEmpty()] [String]$Title, [Parameter( Position=1, Mandatory=$True, ParameterSetName="Default" )] [Parameter( Position=1, Mandatory=$True, ParameterSetName="New-Event:ByDate" )] [Parameter( Position=1, Mandatory=$True, ParameterSetName="New-Event:ByTimestamp" )] [ValidateNotNullOrEmpty()] [String]$Text, [Parameter( Position=2, Mandatory=$False, ParameterSetName="New-Event:ByDate" )] [ValidateNotNullOrEmpty()] [datetime]$DateHappened, [Parameter( Position=2, Mandatory=$False, ParameterSetName="New-Event:ByTimestamp" )] [ValidateNotNullOrEmpty()] [Double]$TimestampHappened, [Parameter( Position=3, Mandatory=$False, ParameterSetName="Default" )] [Parameter( Position=3, Mandatory=$False, ParameterSetName="New-Event:ByDate" )] [Parameter( Position=3, Mandatory=$False, ParameterSetName="New-Event:ByTimestamp" )] [String]$SomeOtherParam, ... |
Here is what I get when I call Get-Help
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
PS> get-help New-Event NAME New-Event SYNOPSIS Post an event to the stream. SYNTAX New-Event [-Title] New-Event [-Title] New-Event [-Title] |
However here is the error I get when I try to call the function with only the two mandatory parameters:
1 2 3 4 5 6 7 8 |
New-Event -Title test -Text text New-Event : Parameter set cannot be resolved using the specified named parameters. At line:1 char:1 + New-Event -Title test -Text text + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidArgument: (:) [New-Event], ParameterBindingException + FullyQualifiedErrorId : AmbiguousParameterSet,New-Event |
I’m missing something here, but I can’t figure out what…
How can I get two parameters that are mutually exclusive and optional?
Answer:
This makes perfect sense. You have 3 parameter sets, and the 2 mandatory parameters are included on every set. How could PowerShell determine which set you meant to use?
Luckily the [CmdletBinding()]
attribute can take a parameter that helps with this exact case: DefaultParameterSetName
. Setting this allows PowerShell to use this set in the case of (certain) ambiguities. Use it like so:
1 2 |
[CmdletBinding(DefaultParameterSetName='Default')] |
Note that in this case, you named it default; it could have been named anything.