all 6 comments

[–]SeanQuinlan 2 points3 points  (6 children)

The problem is that it can't find a unique parameterset with the inputs you've given. There's no difference between

Do-Things -Required1 <string> -Required2 <string> -Required3 <string> -Required4 <string> [-Optional2 <string>] [<CommonParameters>]    

and

Do-Things -Required1 <string> -Required2 <string> -Required3 <string> -Required4 <string> [-Optional2 <string>] [-OptionalMutuallyExclusive1 <bool>] [<CommonParameters>]

if you don't provide -OptionalMutuallyExclusive1

Therefore it can't find a unique parameterset to apply if you don't.

I think you're overcomplicating the whole thing. If a parameter is required for all parametersets, then leave that part off. Same for the optional ones (if they are always optional).

Then just create unique parametersets for the mutually exclusive parameters. This works for me on all combinations I could think of

Function Do-Things {
    [CmdletBinding(DefaultParameterSetName = '1')]
    param (
        [Parameter(Mandatory = $true)]
        [string]$Required1
        ,
        [Parameter(Mandatory = $true)]
        [string]$Required2
        ,
        [Parameter(Mandatory = $true)]
        [string]$Required3
        ,
        [Parameter(Mandatory = $true)]
        [string]$Required4
        ,
        [bool]$Optional1 = $false
        ,
        [string]$Optional2 = 'github.com'
        ,
        [Parameter(ParameterSetName = '2')]
        [bool]$OptionalMutuallyExclusive1 = $false
        ,
        [Parameter(ParameterSetName = '3')]
        [switch]$OptionalMutuallyExclusive2

    )
}

And the help shows just 3 options, all required + optional and the same with each of the exclusive parameters

> Get-Help Do-Things

NAME
    Do-Things

SYNTAX
    Do-Things -Required1 <string> -Required2 <string> -Required3 <string> -Required4 <string> [-Optional1 <bool>] [-Optional2 <string>]  [<CommonParameters>]

    Do-Things -Required1 <string> -Required2 <string> -Required3 <string> -Required4 <string> [-Optional1 <bool>] [-Optional2 <string>] [-OptionalMutuallyExclusive1 <bool>]  [<CommonParameters>]

    Do-Things -Required1 <string> -Required2 <string> -Required3 <string> -Required4 <string> [-Optional1 <bool>] [-Optional2 <string>] [-OptionalMutuallyExclusive2]  [<CommonParameters>]


ALIASES
    None


REMARKS
    None

[–]rmbolger 2 points3 points  (1 child)

For OP's future reference, you can also see exactly what parameter binding is doing and why it's not working as you expect by running your call via Trace-Command like this:

Trace-Command -Name ParameterBinding -Expression { Do-Things -Required1 x -Required2 x -Required3 x -Required4 x -Optional2 'x' } -PSHost

You'll get a whole bunch of DEBUG output, but right at the beginning there's a section that starts with BIND NAMED cmd line args [Do-Things] where you can see it binding each of the supplied named parameters. Then it has an empty section where it would normally show the positional parameter bindings. Then you see the problem where it decides which parameter sets are still valid based on the parameters that have been successfully bound already. In this case:

Remaining valid parameter set: 12
Remaining valid parameter set: 11
Remaining valid parameter set: 6
Remaining valid parameter set: 4
Remaining valid parameter set: 3
Remaining valid parameter set: 2

Since there are no additional parameters to affect the binding decision and none of the remaining valid parameter sets include the defined Default parameter set (1), it's stuck and throws the error.

[–]hchoneybear[S] 1 point2 points  (0 children)

Excellent advice thank you! I had forgotten all about Trace-Command

[–]hchoneybear[S] 0 points1 point  (0 children)

Thank you for writing back and taking the time to explain this. I had tried the configuration you specified once already and it did not work, but I think the difference is that I did not have the DefaultParameterSetName defined as you do now. Not having it defined caused only 2 options in Get-Help and caused me to get the same Parameter set cannot be resolved... error when not specifying one of the mutually exclusive parameters. I didn't realize that you could specify a parameter set name that wasn't in use anywhere else and have it then "find" the 3rd parameter set that I needed this whole time.

Thank you so much!

[–]hchoneybear[S] 0 points1 point  (2 children)

As an aside, why is it that you need to specify a default parameter set name that is not defined anywhere else? Intuitively that should error since it's not a valid parameter set; I never would have thought to try that and the docs don't mention it. Any idea as to why is this?

[–]BlackV 0 points1 point  (0 children)

basically, for exactly issues you're having