Search code examples
powershelldependenciesmutual-exclusionparameter-sets

Complex Parameter sets with dependent and mutually exclusive parameters


I have a requirement in a function that 2 parameters depend on each other, another parameter is mutually exclusionary to the first 2, there are several optional parameters, then 2 parameters that are mutually exclusive.

Below is a prototype of the parameters I am trying to achieve.

function TestParms () {
[CmdletBinding()]
Param (
    # $p1 and $p2 must be used together. Can be used with all other parameters except $p3
    $p1,
    $p2,
    # $P3 cannot be used with $p1 and $p2. Can be used with all other parameters or alone.
    $p3,
    # independent parameters
    $p4,
    $p5,
    $p6,
    # $p7 and $p8 are exclusive to each other but can be used with other parameters, or alone
    $p7,
    $p8
)

    write-host "The parameters work" 
}

To explain, $p1 and $p2 must be used together. Cannot be used with $p3 and can be used without any other parameters. $p3 cannot be used with $p1 and $p2. Can be used alone or with the other parameters. $p4, $p5, and $p5 are optional. $p6 and $p7 are mutually exclusive but either can be used with any other parameters. No parameters are mandatory.

I have tried multiple combinations of parameter sets and cannot get this working. For instance if I try to get parameter $p3 to work both with parameters $p7 and $p8 like this, it fails.

Param (
    # $p1 and $p2 must be used together. Can be used with all other parameters except $p3
    $p1,
    $p2,
    # $P3 cannot be used with $p1 and $p2. Can be used with all other parameters or alone.
    [Parameter(ParameterSetName='p3')]
    [Parameter(ParameterSetName = 'p7.1')]
    [Parameter(ParameterSetName = 'p8.1')]
    $p3,
    # independent parameters
    $p4,
    $p5,
    $p6,
    # $p7 and $p8 are exclusive to each other but can be used with other parameters, or alone
    [Parameter(ParameterSetName = 'p7')]
    [Parameter(ParameterSetName = 'p7.1')]
    $p7,
    [Parameter(ParameterSetName = 'p8')]
    [Parameter(ParameterSetName = 'p8.1')]
    $p8
)

Test-Parms -p3 '3'

Results in a parameter set error, but

Test-Parms -p3 '3' -p7 '7'

Works


Solution

  • The following sets might accomplish what you're looking for:

    function TestParms {
        [CmdletBinding(DefaultParameterSetName = 'independentParameters')]
        Param (
            [Parameter(ParameterSetName = 'p1p2p8', Mandatory)]
            [Parameter(ParameterSetName = 'p1p2p7', Mandatory)]
            [Parameter(ParameterSetName = 'p1p2', Mandatory)]
            $p1,
    
            [Parameter(ParameterSetName = 'p1p2p8', Mandatory)]
            [Parameter(ParameterSetName = 'p1p2p7', Mandatory)]
            [Parameter(ParameterSetName = 'p1p2', Mandatory)]
            $p2,
    
            [Parameter(ParameterSetName = 'p3p8', Mandatory)]
            [Parameter(ParameterSetName = 'p3p7', Mandatory)]
            [Parameter(ParameterSetName = 'p3', Mandatory)]
            $p3,
    
            $p4,
            $p5,
            $p6,
    
            [Parameter(ParameterSetName = 'p3p7', Mandatory)]
            [Parameter(ParameterSetName = 'p1p2p7', Mandatory)]
            [Parameter(ParameterSetName = 'p7', Mandatory)]
            $p7,
    
            [Parameter(ParameterSetName = 'p3p8', Mandatory)]
            [Parameter(ParameterSetName = 'p1p2p8', Mandatory)]
            [Parameter(ParameterSetName = 'p8', Mandatory)]
            $p8
        )
    
        Write-Host 'The parameters work'
    }
    

    Tests:

    # $p1 and $p2 must be used together. Can be used with all other parameters except $p3
    TestParms -p1 a -p2 a             # works
    TestParms -p1 a -p2 a -p3 a       # fails
    TestParms -p1 a -p2 a -p8 a       # works
    TestParms -p1 a -p2 a -p7 a       # works
    TestParms -p1 a -p2 a -p7 a -p4 a # works
    
    # $P3 cannot be used with $p1 and $p2. Can be used with all other parameters or alone.
    TestParms -p3 a             # works
    TestParms -p3 a -p7 a       # works
    TestParms -p3 a -p7 a -p4 a # works
    TestParms -p3 a -p8 a -p7 a # fails
    
    # $p7 and $p8 are exclusive to each other but can be used with other parameters, or alone
    TestParms -p7 a             # works
    TestParms -p8 a             # works
    TestParms -p7 a -p8 a       # fails
    TestParms -p7 a -p1 a -p2 a # works
    
    # independent parameters
    TestParms -p4 a             # works
    TestParms -p4 a -p5 a -p6 a # works
    TestParms                   # works