I'm struggling to understand the behavior of parameter sets and positional binding. Here is the sample function.
function Test-PositionBinding {
[CmdletBinding(DefaultParameterSetName = 'ParamSet2')]
param (
[Parameter(ParameterSetName='ParamSet1',Position = 0)]
[int]
$param1,
[Parameter(ParameterSetName='ParamSet1',Position = 1)]
[int]
$param2,
[Parameter(ParameterSetName='ParamSet2',Position = 0)]
[int]
$param3
)
process {
$PSCmdlet.ParameterSetName
$param1
$param2
$param3
}
}
Based on the help output it would seem that calling the function with a single int should use paramset1 and calling it with 2 int should use paramset2 which is what i would expect.
SYNTAX
Test-PositionBinding [[-param3] <int>] [<CommonParameters>]
Test-PositionBinding [[-param1] <int>] [[-param2] <int>] [<CommonParameters>]
However, I receive the following output.
PS C:\> Test-PositionBinding 1
ParamSet2
0
0
1
PS C:\> Test-PositionBinding 1 2
Test-PositionBinding: A positional parameter cannot be found that accepts argument '2'.
I would have expected the following.
PS C:\> Test-PositionBinding 1 2
ParamSet1
1
2
0
If we change the type of param1 to a string the function works as expected.
PS C:\> Test-PositionBinding 1
ParamSet2
0
1
PS C:\> Test-PositionBinding 'abc'
ParamSet1
abc
0
0
PS C:\> Test-PositionBinding 'abc' 2
ParamSet1
abc
2
0
What is it that I am misunderstanding about the way PS interprets parameter sets?
Ultimately my question, is why is PS unable to differentiate between 2 parameter sets with positional binding and different parameter counts if the first parameter is of the same type between sets.
If you add an IF you can see when you choose param 1 or 2 you are in paramset 1
if you choose param1 or 2 you can't select param 3 or 4
if you run Test-postionbinding 1
Then since param1 is defined as 0 it will powershell will automatically bind the first parameter passed to the function to position 0.
if you pass 0 -param4 1
Param3 will have a value of 0 and param4 will be 1 and you fall into paramset2.
If you specify param1 then your only other parameter is param2 because its a member of Paramset1
If you choose param3 then the only other available param is param4 because it's part of paramset2
Observing position 2 binding
Observing paramset2
using no parameter names and forcing powershell to use the binding specified: Test-PositionBinding 0 1 Test-PositionBinding : A position