about_Parameter_Sets
Short description
Describes how to define and use parameter sets in advanced functions.
Long description
PowerShell uses parameter sets to enable you to write a single function that can do different actions for different scenarios. Parameter sets enable you to expose different parameters to the user. And, to return different information based on the parameters specified by the user. You can only use one parameter set at a time.
Parameter set requirements
The following requirements apply to all parameter sets.
If no parameter set is specified for a parameter, the parameter belongs to all parameter sets.
Each parameter set must have a unique combination of parameters. If possible, at least one of the unique parameters should be a mandatory parameter.
A parameter set that contains multiple positional parameters must define unique positions for each parameter. No two positional parameters can specify the same position.
Only one parameter in a set can declare the
ValueFromPipeline
keyword with a value oftrue
. Multiple parameters can define theValueFromPipelineByPropertyName
keyword with a value oftrue
.
Note
There is a limit of 32 parameter sets.
Default parameter sets
When multiple parameter sets are defined, the DefaultParameterSetName
keyword
of the CmdletBinding attribute specifies the default parameter set.
PowerShell uses the default parameter set when it can't determine the parameter
set to use based on the information provided to the command. For more
information about the CmdletBinding attribute, see
about_Functions_CmdletBindingAttribute.
Declaring parameter sets
To create a parameter set, you must specify the ParameterSetName
keyword of
the Parameter attribute for every parameter in the parameter set. For
parameters that belong to multiple parameter sets, add a Parameter
attribute for each parameter set.
The Parameter attribute enables you to define the parameter differently for each parameter set. For example, you can define a parameter as mandatory in one set and optional in another. However, each parameter set must contain at least one unique parameter.
Parameters that don't have an assigned parameter set name belong to all parameter sets.
Examples
The following example function counts the number lines, characters, and words in a text file. Using parameters, you can specify which values you want returned and which files you want to measure. There are four parameter sets defined:
- Path
- PathAll
- LiteralPath
- LiteralPathAll
function Measure-Lines {
[CmdletBinding(DefaultParameterSetName = 'Path')]
param (
[Parameter(Mandatory, ParameterSetName = 'Path', Position = 0)]
[Parameter(Mandatory, ParameterSetName = 'PathAll', Position = 0)]
[string[]]$Path,
[Parameter(Mandatory, ParameterSetName = 'LiteralPathAll', ValueFromPipeline)]
[Parameter(Mandatory, ParameterSetName = 'LiteralPath', ValueFromPipeline)]
[string[]]$LiteralPath,
[Parameter(ParameterSetName = 'Path')]
[Parameter(ParameterSetName = 'LiteralPath')]
[switch]$Lines,
[Parameter(ParameterSetName = 'Path')]
[Parameter(ParameterSetName = 'LiteralPath')]
[switch]$Words,
[Parameter(ParameterSetName = 'Path')]
[Parameter(ParameterSetName = 'LiteralPath')]
[switch]$Characters,
[Parameter(Mandatory, ParameterSetName = 'PathAll')]
[Parameter(Mandatory, ParameterSetName = 'LiteralPathAll')]
[switch]$All,
[Parameter(ParameterSetName = 'Path')]
[Parameter(ParameterSetName = 'PathAll')]
[switch]$Recurse
)
begin {
if ($All) {
$Lines = $Words = $Characters = $true
}
elseif (($Words -eq $false) -and ($Characters -eq $false)) {
$Lines = $true
}
}
process {
if ($Path) {
$Files = Get-ChildItem -Path $Path -Recurse:$Recurse -File
}
else {
$Files = Get-ChildItem -LiteralPath $LiteralPath -File
}
foreach ($file in $Files) {
$result = [ordered]@{ }
$result.Add('File', $file.fullname)
$content = Get-Content -LiteralPath $file.fullname
if ($Lines) { $result.Add('Lines', $content.Length) }
if ($Words) {
$wc = 0
foreach ($line in $content) { $wc += $line.split(' ').Length }
$result.Add('Words', $wc)
}
if ($Characters) {
$cc = 0
foreach ($line in $content) { $cc += $line.Length }
$result.Add('Characters', $cc)
}
New-Object -TypeName psobject -Property $result
}
}
}
Each parameter set must have a unique parameter or a unique combination of
parameters. The Path
and PathAll
parameter sets are very similar but the
All parameter is unique to the PathAll
parameter set. The same is true
with the LiteralPath
and LiteralPathAll
parameter sets. Even though the
PathAll
and LiteralPathAll
parameter sets both have the All parameter,
the Path and LiteralPath parameters differentiate them.
Use Get-Command -Syntax
shows you the syntax of each parameter set. However
it doesn't show the name of the parameter set. The following example shows
which parameters can be used in each parameter set.
(Get-Command Measure-Lines).ParameterSets |
Select-Object -Property @{n='ParameterSetName';e={$_.name}},
@{n='Parameters';e={$_.ToString()}}
ParameterSetName Parameters
---------------- ----------
Path [-Path] <string[]> [-Lines] [-Words] [-Characters] [-Recurse] [<CommonParameters>]
PathAll [-Path] <string[]> -All [-Recurse] [<CommonParameters>]
LiteralPath -LiteralPath <string[]> [-Lines] [-Words] [-Characters] [<CommonParameters>]
LiteralPathAll -LiteralPath <string[]> -All [<CommonParameters>]
Parameter sets in action
The example uses the PathAll
parameter set.
Measure-Lines test* -All
File Lines Words Characters
---- ----- ----- ----------
C:\temp\test\test.help.txt 31 562 2059
C:\temp\test\test.md 30 1527 3224
C:\temp\test\test.ps1 3 3 79
C:\temp\test\test[1].txt 31 562 2059
Error using parameters from multiple sets
In this example, unique parameters from different parameter sets are used.
Get-ChildItem -Path $PSHOME -LiteralPath $PSHOME
Get-ChildItem: Parameter set cannot be resolved using the specified named
parameters. One or more parameters issued cannot be used together or an
insufficient number of parameters were provided.
The Path and LiteralPath parameters are unique to different parameter
sets of the Get-ChildItem
cmdlet. When the parameters are run together in the
same cmdlet, an error is thrown. Only one parameter set can be used per cmdlet
call at a time.
How to know which parameter set is used
The automatic variable $PSCmdlet
provides the ParameterSetName property.
This property contains the name of the parameter set being used. You can use
this property in your function to determine which parameter set is being used
to select parameter set-specific behavior.
function Get-ParameterSetName {
[CmdletBinding(DefaultParameterSetName = 'Set1')]
param (
[Parameter(ParameterSetName = 'Set1', Position = 0)]
$Var1,
[Parameter(ParameterSetName = 'Set2', Position = 0)]
$Var2,
[Parameter(ParameterSetName = 'Set1', Position = 1)]
[Parameter(ParameterSetName = 'Set2', Position = 1)]
$Var3,
[Parameter(Position = 2)]
$Var4
)
"Using Parameter set named '$($PSCmdlet.ParameterSetName)'"
switch ($PSCmdlet.ParameterSetName) {
'Set1' {
"`$Var1 = $Var1"
"`$Var3 = $Var3"
"`$Var4 = $Var4"
break
}
'Set2' {
"`$Var2 = $Var2"
"`$Var3 = $Var3"
"`$Var4 = $Var4"
break
}
}
}
PS> Get-ParameterSetName 1 2 3
Using Parameter set named 'Set1'
$Var1 = 1
$Var3 = 2
$Var4 = 3
PS> Get-ParameterSetName -Var2 1 2 3
Using Parameter set named 'Set2'
$Var2 = 1
$Var3 = 2
$Var4 = 3