5

I'm writing a function for which two parameters should be exclusive and optional.

Here are valid inputs:

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:

new-event -Title sometitle -Text sometext -DateHappened (get-date) -TimestampHappened 1234567 -SomeOtherOptionalParam somestring

Here is my code so far:

[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:

PS> get-help New-Event

NAME
    New-Event

SYNOPSIS
    Post an event to the stream.


SYNTAX
    New-Event [-Title] <String> [-Text] <String> [[-TimestampHappened] <Double>] [[-Priority] <String>] [[-Hostname] <String>] [[-Tags] <String[]>] [[-AlertType] <String>] [<CommonParameters>]

    New-Event [-Title] <String> [-Text] <String> [[-DateHappened] <DateTime>] [[-Priority] <String>] [[-Hostname] <String>] [[-Tags] <String[]>] [[-AlertType] <String>]  <String>] [<CommonParameters>]

    New-Event [-Title] <String> [-Text] <String> [[-Priority] <String>] [[-Hostname] <String>] [[-Tags] <String[]>] [[-AlertType] <String>] [<CommonParameters>]

However here is the error I get when I try to call the function with only the two mandatory parameters:

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?

1
  • 1
    [CmdletBinding(DefaultParameterSetName='Default')] Commented Feb 11, 2017 at 0:16

1 Answer 1

6

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:

[CmdletBinding(DefaultParameterSetName='Default')]

Note that in this case, you named it default; it could have been named anything.

Sign up to request clarification or add additional context in comments.

1 Comment

Ah, indeed it makes sense. I had been obsessing over the 2 date parameters when the problem was elsewhere. Thanks!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.