Mutually exclusive powershell parameters

namenlos picture namenlos · Nov 20, 2009 · Viewed 15.5k times · Source

SCENARIO

  • I'm writing a cmdlet for Powershell 2.0 using Visual Studio 2008 and .NET 3.5
  • the cmdlet requires 3 arguments.

my intended grammar of the cmdlet is something like this:

cmdletname [foo|bar] p1, p2
  • That reads as the user must give a value for "-foo" or "-bar" but can't give both together.

EXAMPLE OF VALID INPUT

cmdletname -foo xxx -p1 hello  -p2 world
cmdletname -bar yyy -p1 hello  -p2 world

EXAMPLE OF INVALID INPUT

cmdletname -foo xxx -bar yyy -p1 hello  -p2 world

MY QUESTION

  • My question is on how to do this in powershell so that it does all the checking for me - or if that is possible at all.
  • I know I can use just have two optional parameters for foo and bar and simply do the error checking manually. That's how I have it implemented currently.
  • Alternatively, I am interested in suggestions for different approaches.

Answer

Joey picture Joey · Nov 20, 2009

You can use the parameter attribute to declare multiple parameter sets. You then simply assign parameters that are mutually exclusive to different parameter sets.

EDIT:

This is also documented in 'about_Functions_Advanced_Parameters', under the section "ParameterSetName Named Argument". This is how different sets of parameters is handled with cmdlets like Get-Random (which has mutually exclusive parameters):

> get-random -input 4 -max 77
Get-Random : Parameter set cannot be resolved using the specified named parameters.
At line:1 char:11
+ get-random <<<<  -input 4 -max 77
    + CategoryInfo          : InvalidArgument: (:) [Get-Random], ParameterBindingException
    + FullyQualifiedErrorId : AmbiguousParameterSet,Microsoft.PowerShell.Commands.GetRandomCommand

Here's an example of doing it in a function:

function exclusive_params() { 
    param( 
        [parameter(ParameterSetName="seta")]$one,
        [parameter(ParameterSetName="setb")]$two, 
        $three 
    )
    "one: $one"; "two: $two"; "three: $three" 
}

The parameters one and two are in different parameter sets, so they cannot be specified together:

> exclusive_params -one foo -two bar -three third
exclusive_params : Parameter set cannot be resolved using the specified named parameters.
At line:1 char:17
+ exclusive_params <<<<  -one foo -two bar -three third
    + CategoryInfo          : InvalidArgument: (:) [exclusive_params], ParameterBindingException
    + FullyQualifiedErrorId : AmbiguousParameterSet,exclusive_params

Which is the same error I got with Get-Random. But I can use the parameters independently:

> exclusive_params -one foo -three third
one: foo
two:
three: third

...or:

> exclusive_params -two bar -three third
one:
two: bar
three: third