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 of true. Multiple parameters can define the ValueFromPipelineByPropertyName keyword with a value of true. [!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] [-Lines] [-Words] [-Characters] [-Recurse] [] PathAll [-Path] -All [-Recurse] [] LiteralPath -LiteralPath [-Lines] [-Words] [-Characters] [] LiteralPathAll -LiteralPath -All [] 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 can't be resolved using the specified named parameters. At line:1 char:1 + Get-ChildItem -Path $PSHOME -LiteralPath $PSHOME + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidArgument: (:) [Get-ChildItem], ParameterBindingException + FullyQualifiedErrorId : AmbiguousParameterSet,Microsoft.PowerShell.Commands.GetChildItemCommand 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