Reputation: 640
I made a simple powershell script that has two parameters. If I try to execute the script with no arguments, it works fine. If I try to execute it with either one of the two arguments, it works fine. When I try to run the script with both arguments, I get the following error:
Parameter set cannot be resolved using the specified named parameters.
It also has a tidbit in there about AmibiguousParameterSet.
The parameter section of my script looks like this:
[CmdletBinding(DefaultParameterSetName="None")]
param(
[Parameter(Mandatory=$False, ParameterSetName="BuildExclude")]
[ValidateSet('proj1','proj2', 'proj3', 'proj4')]
[string[]]$BuildExclude,
[Parameter(Mandatory=$False, ParameterSetName="SkipDbRestore")]
[switch]$SkipDbRestore
)
These usages work:
.\RunScript.ps1 -BuildExclude proj1, proj2
.\RunScript.ps1 -SkipDbRestore
.\RunScript.ps1
This usage doesn't work for the aforementioned reason:
.RunScript.ps1 -BuildExclude proj1, proj2 -SkipDbRestore
It doesn't work even if I reverse the order of the arguments. I tried adding in parameter positions, making BuildExclude=0 and SkipDbRestore=1 in the hope that I'd be able to get them working together if I at least keep them in that order. But that gives me the same ambiguity error. What am I missing? Ideally I'd like to be able to call the script with the parameters in any order and have it do the right thing.
Upvotes: 1
Views: 1881
Reputation: 3341
Parameter sets are a lot like overloaded functions - you use them to indicate which params you require. Your original example had two parameter sets, with one param in each. This forces the user to choose one of them. In another situation you might have a function which either takes param param1, OR param2 AND param3. You'd express that as such:
function Doit
{
Param(
[Parameter(Mandatory=$true, ParameterSetName="paramset1")]
$param1,
[Parameter(Mandatory=$true, ParameterSetName="paramset2")]
$param2,
[Parameter(Mandatory=$true, ParameterSetName="paramset2")]
$param3
)
#code
}
Param sets in combination with mandatory true/false gives a tremendous amount of control of how params are passed into your function.
In your example, you simply don't need to specify a param set, since you only have one. So the param header of your function can be specified like this:
function doit2
{
param(
[ValidateSet('proj1','proj2', 'proj3', 'proj4')]
[string[]]$BuildExclude,
[switch]$SkipDbRestore
)
}
Upvotes: 6