1

I want to achieve the following in my parameter sets:

function [A | B] [C | D] (E) (F)

In English as concise as possible, I would like A, B, C and D to be Manadatory=$true but A and B can't be in the same command nor can C and D. E and F will always be optional.

I figured I could expand this with multiple ParameterSetName attributes following the below logic:

function A C (E) (F)
function A D (E) (F)
function B C (E) (F)
function B D (E) (F)

However the below sentence says each parameter set must have a unqiue parameter, but as you can see I use A and B twice each. The only way for the PowerShell runtime to identify them as unique parameter sets is by looking at two paremters, not just one.

Each parameter set must have a unique parameter that the Windows PowerShell runtime can use to expose the appropriate parameter set

Source

Is there some way to achieve this?

codaamok
  • 717
  • 3
  • 11
  • 21
  • 1
    In some cases (IMO) the code may be easier to read to declare all your parameters and custom validate in the script rather than trying to express complex logic using `Parameter` declarations. – Bill_Stewart Dec 06 '16 at 15:51
  • 1
    You might also explore whether you can use dynamic parameters. See `about_Functions_Advanced_Parameters` (`DynamicParam` keyword) for more information. – Bill_Stewart Dec 06 '16 at 21:28
  • 1
    @Bill_Stewart but then I would miss out on the advantage of enabling users to try `Get-Help` – codaamok Dec 07 '16 at 10:22

1 Answers1

1

I think you'll need to create 4 parameter sets, A-C, A-D, B-C and B-D, you will need to define all the parameters in each set, e. g. you'll need to define A twice, once in set A-C and once in set A-D.

Don't put E or F in any set.

I created some mock code to show what I mean:

function Test-abcdef
{
    param
    (
        [Parameter(Mandatory = $true,ParameterSetName = 'a-c')]
        [Parameter(Mandatory = $true,ParameterSetName = 'a-d')]
        $a,
        
        [Parameter(Mandatory = $true,ParameterSetName = 'b-c')]
        [Parameter(Mandatory = $true,ParameterSetName = 'b-d')]
        $b,

        [Parameter(Mandatory = $true,ParameterSetName = 'a-c')]
        [Parameter(Mandatory = $true,ParameterSetName = 'b-c')]
        $c,
        
        [Parameter(Mandatory = $true,ParameterSetName = 'a-d')]
        [Parameter(Mandatory = $true,ParameterSetName = 'b-d')]
        $d,
        
        [Parameter]
        $e,
        
        [Parameter]
        $f
    )
    
    switch ($PsCmdlet.ParameterSetName)
    {
        'a-c' {
            Write-Output $a $c
            break
        }
        'a-d' {
            Write-Output $a $d
            break
        }
        'b-c' {
            Write-Output $b $c
            break
        }
        'b-d' {
            Write-Output $b $d
            break
        }
    }
}

help Test-abcdef

If you do help on the function as above it gives you the following:

NAME
Test-abcdef

SYNTAX
Test-abcdef -a <Object> -d <Object> [-e <Parameter>] [-f <Parameter>]  [<CommonParameters>]

Test-abcdef -a <Object> -c <Object> [-e <Parameter>] [-f <Parameter>]  [<CommonParameters>]

Test-abcdef -b <Object> -d <Object> [-e <Parameter>] [-f <Parameter>]  [<CommonParameters>]

Test-abcdef -b <Object> -c <Object> [-e <Parameter>] [-f <Parameter>]  [<CommonParameters>]

Which I believe is exactly what you wanted.

stackprotector
  • 10,498
  • 4
  • 35
  • 64
Jim Moyle
  • 637
  • 4
  • 11
  • Thanks Jim, I really appreciate your help. I'm totally confused on how it works because my interpretation of the given quote and all the info in the source link was that all parameter sets needed a single unique parameter for the parameter set to be resolved at runtime. – codaamok Dec 07 '16 at 10:24
  • I believe it needs a unique set of parameters rather than just a single one. – Jim Moyle Dec 07 '16 at 10:59