About Functions Advanced Parameters
Short description
Explains how to add parameters to advanced functions.
Long description
You can add parameters to the advanced functions that you write, and use parameter attributes and arguments to limit the parameter values that function users submit with the parameter.
The parameters that you add to your function are available to users in addition to the common parameters that PowerShell adds automatically to all cmdlets and advanced functions. For more information about the PowerShell common parameters, see about_CommonParameters.
Beginning in PowerShell 3.0, you can use splatting with @Args
to represent
the parameters in a command. Splatting is valid on simple and advanced
functions. For more information, see about_Functions and about_Splatting.
Static parameters
Static parameters are parameters that are always available in the function. Most parameters in PowerShell cmdlets and scripts are static parameters.
The following example shows the declaration of a ComputerName parameter that has the following characteristics:
- It's mandatory (required).
- It takes input from the pipeline.
- It takes an array of strings as input.
Param(
[Parameter(Mandatory=$true,
ValueFromPipeline=$true)]
[String[]]
$ComputerName
)
Attributes of parameters
This section describes the attributes that you can add to function parameters.
All attributes are optional. However, if you omit the CmdletBinding attribute, then to be recognized as an advanced function, the function must include the Parameter attribute.
You can add one or multiple attributes in each parameter declaration. There's no limit to the number of attributes that you can add to a parameter declaration.
Parameter attribute
The Parameter attribute is used to declare the attributes of function parameters.
The Parameter attribute is optional, and you can omit it if none of the parameters of your functions need attributes. But, to be recognized as an advanced function, rather than a simple function, a function must have either the CmdletBinding attribute or the Parameter attribute, or both.
The Parameter attribute has arguments that define the characteristics of the parameter, such as whether the parameter is mandatory or optional.
Use the following syntax to declare the Parameter attribute, an argument, and an argument value. The parentheses that enclose the argument and its value must follow Parameter with no intervening space.
Param(
[Parameter(Argument=value)]
$ParameterName
)
Use commas to separate arguments within the parentheses. Use the following syntax to declare two arguments of the Parameter attribute.
Param(
[Parameter(Argument1=value1,
Argument2=value2)]
)
If you use the Parameter attribute without arguments, as an alternative to using the CmdletBinding attribute, the parentheses that follow the attribute name are still required.
Param(
[Parameter()]
$ParameterName
)
Mandatory argument
The Mandatory
argument indicates that the parameter is required. If this
argument isn't specified, the parameter is optional.
The following example declares the ComputerName parameter. It uses the
Mandatory
argument to make the parameter mandatory.
Param(
[Parameter(Mandatory=$true)]
[String[]]
$ComputerName
)
Position argument
The Position
argument determines whether the parameter name is required when
the parameter is used in a command. When a parameter declaration includes the
Position
argument, the parameter name can be omitted and PowerShell
identifies the unnamed parameter value by its position, or order, in the list
of unnamed parameter values in the command.
If the Position
argument isn't specified, the parameter name, or a parameter
name alias or abbreviation, must precede the parameter value whenever the
parameter is used in a command.
By default, all function parameters are positional. PowerShell assigns position
numbers to parameters in the order in which the parameters are declared in the
function. To disable this feature, set the value of the PositionalBinding
argument of the CmdletBinding attribute to $False
. The Position
argument takes precedence over the value of the PositionalBinding
argument
for the parameters on which it's declared. For more information, see
PositionalBinding
in
about_Functions_CmdletBindingAttribute.
The value of the Position
argument is specified as an integer. A position
value of 0 represents the first position in the command, a position value
of 1 represents the second position in the command, and so on.
If a function has no positional parameters, PowerShell assigns positions to
each parameter based on the order in which the parameters are declared.
However, as a best practice, don't rely on this assignment. When you want
parameters to be positional, use the Position
argument.
The following example declares the ComputerName parameter. It uses the
Position
argument with a value of 0. As a result, when -ComputerName
is
omitted from command, its value must be the first or only unnamed parameter
value in the command.
Param(
[Parameter(Position=0)]
[String[]]
$ComputerName
)
Note
When the Get-Help
cmdlet displays the corresponding Position parameter
attribute, the position value is incremented by one.
For example, a parameter with a Position
argument value of 0 has a
parameter attribute of Position=1.
ParameterSetName argument
The ParameterSetName
argument specifies the parameter set to which a
parameter belongs. If no parameter set is specified, the parameter belongs to
all the parameter sets defined by the function. Therefore, to be unique, each
parameter set must have at least one parameter that isn't a member of any other
parameter set.
Note
For a cmdlet or function, there is a limit of 32 parameter sets.
The following example declares a ComputerName parameter in the Computer
parameter set, a UserName parameter in the User
parameter set, and a
Summary parameter in both parameter sets.
Param(
[Parameter(Mandatory=$true,
ParameterSetName="Computer")]
[String[]]
$ComputerName,
[Parameter(Mandatory=$true,
ParameterSetName="User")]
[String[]]
$UserName,
[Parameter(Mandatory=$false)]
[Switch]
$Summary
)
You can specify only one ParameterSetName
value in each argument and only one
ParameterSetName
argument in each Parameter attribute. To indicate that a
parameter appears in more than one parameter set, add additional Parameter
attributes.
The following example explicitly adds the Summary parameter to the
Computer
and User
parameter sets. The Summary parameter is optional in
the Computer
parameter set and mandatory in the User
parameter set.
Param(
[Parameter(Mandatory=$true,
ParameterSetName="Computer")]
[String[]]
$ComputerName,
[Parameter(Mandatory=$true,
ParameterSetName="User")]
[String[]]
$UserName,
[Parameter(Mandatory=$false, ParameterSetName="Computer")]
[Parameter(Mandatory=$true, ParameterSetName="User")]
[Switch]
$Summary
)
For more information about parameter sets, see Cmdlet Parameter Sets.
ValueFromPipeline argument
The ValueFromPipeline
argument indicates that the parameter accepts input
from a pipeline object. Specify this argument if the function accepts the
entire object, not just a property of the object.
The following example declares a ComputerName parameter that's mandatory and accepts an object that's passed to the function from the pipeline.
Param(
[Parameter(Mandatory=$true,
ValueFromPipeline=$true)]
[String[]]
$ComputerName
)
ValueFromPipelineByPropertyName argument
The ValueFromPipelineByPropertyName
argument indicates that the parameter
accepts input from a property of a pipeline object. The object property must
have the same name or alias as the parameter.
For example, if the function has a ComputerName parameter, and the piped object has a ComputerName property, the value of the ComputerName property is assigned to the function's ComputerName parameter.
The following example declares a ComputerName parameter that's mandatory and accepts input from the object's ComputerName property that's passed to the function through the pipeline.
Param(
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true)]
[String[]]
$ComputerName
)
Note
A typed parameter that accepts pipeline input (by Value
) or
(by PropertyName
) enables use of delay-bind script blocks on the
parameter.
The delay-bind script block is run automatically during
ParameterBinding. The result is bound to the parameter. Delay binding
does not work for parameters defined as type ScriptBlock
or
System.Object
, the script block is passed through without being
invoked.
You can read about delay-bind script blocks here about_Script_Blocks.md.
ValueFromRemainingArguments argument
The ValueFromRemainingArguments
argument indicates that the parameter accepts
all the parameter's values in the command that aren't assigned to other
parameters of the function.
There's a known issue for using collections with ValueFromRemainingArguments where the passed-in collection is treated as a single element.
The following example demonstrates this known issue. The Remaining parameter should contain one at index 0 and two at index 1. Instead, both elements are combined into a single entity.
function Test-Remainder
{
param(
[string]
[Parameter(Mandatory = $true, Position=0)]
$Value,
[string[]]
[Parameter(Position=1, ValueFromRemainingArguments)]
$Remaining)
"Found $($Remaining.Count) elements"
for ($i = 0; $i -lt $Remaining.Count; $i++)
{
"${i}: $($Remaining[$i])"
}
}
Test-Remainder first one,two
Found 1 elements
0: one two
Note
This issue is resolved in PowerShell 6.2.
HelpMessage argument
The HelpMessage
argument specifies a string that contains a brief description
of the parameter or its value. PowerShell displays this message in the prompt
that appears when a mandatory parameter value is missing from a command. This
argument has no effect on optional parameters.
The following example declares a mandatory ComputerName parameter and a help message that explains the expected parameter value.
Param(
[Parameter(Mandatory=$true,
HelpMessage="Enter one or more computer names separated by commas.")]
[String[]]
$ComputerName
)
Alias attribute
The Alias attribute establishes an alternate name for the parameter. There's no limit to the number of aliases that you can assign to a parameter.
The following example shows a parameter declaration that adds the CN and MachineName aliases to the mandatory ComputerName parameter.
Param(
[Parameter(Mandatory=$true)]
[Alias("CN","MachineName")]
[String[]]
$ComputerName
)
Parameter and variable validation attributes
Validation attributes direct PowerShell to test the parameter values that users submit when they call the advanced function. If the parameter values fail the test, an error is generated and the function isn't called. You can also use some of the validation attributes to restrict the values that users can specify for variables.
AllowNull validation attribute
The AllowNull attribute allows the value of a mandatory parameter to be
$null
. The following example declares a ComputerName parameter that can
have a null value.
Param(
[Parameter(Mandatory=$true)]
[AllowNull()]
[String]
$ComputerName
)
AllowEmptyString validation attribute
The AllowEmptyString attribute allows the value of a mandatory parameter to
be an empty string (""
). The following example declares a ComputerName
parameter that can have an empty string value.
Param(
[Parameter(Mandatory=$true)]
[AllowEmptyString()]
[String]
$ComputerName
)
AllowEmptyCollection validation attribute
The AllowEmptyCollection attribute allows the value of a mandatory
parameter to be an empty collection @()
. The following example declares a
ComputerName parameter that can have an empty collection value.
Param(
[Parameter(Mandatory=$true)]
[AllowEmptyCollection()]
[String[]]
$ComputerName
)
ValidateCount validation attribute
The ValidateCount attribute specifies the minimum and maximum number of parameter values that a parameter accepts. PowerShell generates an error if the number of parameter values in the command that calls the function is outside that range.
The following parameter declaration creates a ComputerName parameter that takes one to five parameter values.
Param(
[Parameter(Mandatory=$true)]
[ValidateCount(1,5)]
[String[]]
$ComputerName
)
ValidateLength validation attribute
The ValidateLength attribute specifies the minimum and maximum number of characters in a parameter or variable value. PowerShell generates an error if the length of a value specified for a parameter or a variable is outside of the range.
In the following example, each computer name must have one to ten characters.
Param(
[Parameter(Mandatory=$true)]
[ValidateLength(1,10)]
[String[]]
$ComputerName
)
In the following example, the value of the variable $number
must be a minimum
of one character in length, and a maximum of ten characters.
[Int32][ValidateLength(1,10)]$number = 01
ValidatePattern validation attribute
The ValidatePattern attribute specifies a regular expression that's compared to the parameter or variable value. PowerShell generates an error if the value doesn't match the regular expression pattern.
In the following example, the parameter value must contain a four-digit number, and each digit must be a number zero to nine.
Param(
[Parameter(Mandatory=$true)]
[ValidatePattern("[0-9][0-9][0-9][0-9]")]
[String[]]
$ComputerName
)
In the following example, the value of the variable $number
must be exactly a
four-digit number, and each digit must be a number zero to nine.
[Int32][ValidatePattern("^[0-9][0-9][0-9][0-9]$")]$number = 1111
ValidateRange validation attribute
The ValidateRange attribute specifies a numeric range for each parameter or variable value. PowerShell generates an error if any value is outside that range. In the following example, the value of the Attempts parameter must be between zero and ten.
Param(
[Parameter(Mandatory=$true)]
[ValidateRange(0,10)]
[Int]
$Attempts
)
In the following example, the value of the variable $number
must be between
zero and ten.
[Int32][ValidateRange(0,10)]$number = 5
ValidateScript validation attribute
The ValidateScript attribute specifies a script that is used to validate a
parameter or variable value. PowerShell pipes the value to the script, and
generates an error if the script returns $false
or if the script throws an
exception.
When you use the ValidateScript attribute, the value that's being validated
is mapped to the $_
variable. You can use the $_
variable to refer to the
value in the script.
In the following example, the value of the EventDate parameter must be greater than or equal to the current date.
Param(
[Parameter(Mandatory=$true)]
[ValidateScript({$_ -ge (Get-Date)})]
[DateTime]
$EventDate
)
In the following example, the value of the variable $date
must be greater
than or equal to the current date and time.
[DateTime][ValidateScript({$_ -ge (Get-Date)})]$date = (Get-Date)
ValidateSet attribute
The ValidateSet attribute specifies a set of valid values for a parameter or variable. PowerShell generates an error if a parameter or variable value doesn't match a value in the set. In the following example, the value of the Detail parameter can only be Low, Average, or High.
Param(
[Parameter(Mandatory=$true)]
[ValidateSet("Low", "Average", "High")]
[String[]]
$Detail
)
In the following example, the value of the variable $flavor
must be either
Chocolate, Strawberry, or Vanilla.
[ValidateSet("Chocolate", "Strawberry", "Vanilla")]
[String]$flavor = "Strawberry"
The validation occurs whenever that variable is assigned even within the script. For example, the following results in an error at runtime:
Param(
[ValidateSet("hello", "world")]
[String]$Message
)
$Message = "bye"
ValidateNotNull validation attribute
The ValidateNotNull attribute specifies that the parameter value can't be
$null
. PowerShell generates an error if the parameter value is $null
.
The ValidateNotNull attribute is designed to be used when the type of the
parameter value isn't specified or when the specified type accepts a value of
$null
. If you specify a type that doesn't accept a $null
value, such as a
string, the $null
value is rejected without the ValidateNotNull
attribute, because it doesn't match the specified type.
In the following example, the value of the ID parameter can't be $null
.
Param(
[Parameter(Mandatory=$true)]
[ValidateNotNull()]
$ID
)
ValidateNotNullOrEmpty validation attribute
The ValidateNotNullOrEmpty attribute specifies that the parameter value
can't be $null
and can't be an empty string (""
). PowerShell generates an
error if the parameter is used in a function call, but its value is $null
, an
empty string (""
), or an empty array @()
.
Param(
[Parameter(Mandatory=$true)]
[ValidateNotNullOrEmpty()]
[String[]]
$UserName
)
Dynamic parameters
Dynamic parameters are parameters of a cmdlet, function, or script that are available only under certain conditions.
For example, several provider cmdlets have parameters that are available only
when the cmdlet is used in the provider drive, or in a particular path of the
provider drive. For example, the Encoding parameter is available on the
Add-Content
, Get-Content
, and Set-Content
cmdlets only when it's used in
a file system drive.
You can also create a parameter that appears only when another parameter is used in the function command or when another parameter has a certain value.
Dynamic parameters can be useful, but use them only when necessary, because
they can be difficult for users to discover. To find a dynamic parameter, the
user must be in the provider path, use the ArgumentList parameter of the
Get-Command
cmdlet, or use the Path parameter of Get-Help
.
To create a dynamic parameter for a function or script, use the DynamicParam
keyword.
The syntax is as follows:
DynamicParam {<statement-list>}
In the statement list, use an If
statement to specify the conditions under
which the parameter is available in the function.
Use the New-Object
cmdlet to create a
System.Management.Automation.RuntimeDefinedParameter object to represent
the parameter and specify its name.
You can use a New-Object
command to create a
System.Management.Automation.ParameterAttribute object to represent
attributes of the parameter, such as Mandatory, Position, or
ValueFromPipeline or its parameter set.
The following example shows a sample function with standard parameters named
Name and Path, and an optional dynamic parameter named DP1. The
DP1 parameter is in the PSet1
parameter set and has a type of Int32
.
The DP1 parameter is available in the Get-Sample
function only when the
value of the Path parameter starts with HKLM:
, indicating that it's being
used in the HKEY_LOCAL_MACHINE
registry drive.
function Get-Sample {
[CmdletBinding()]
Param([String]$Name, [String]$Path)
DynamicParam
{
if ($Path.StartsWith("HKLM:"))
{
$attributes = New-Object -Type `
System.Management.Automation.ParameterAttribute
$attributes.ParameterSetName = "PSet1"
$attributes.Mandatory = $false
$attributeCollection = New-Object `
-Type System.Collections.ObjectModel.Collection[System.Attribute]
$attributeCollection.Add($attributes)
$dynParam1 = New-Object -Type `
System.Management.Automation.RuntimeDefinedParameter("DP1", [Int32],
$attributeCollection)
$paramDictionary = New-Object `
-Type System.Management.Automation.RuntimeDefinedParameterDictionary
$paramDictionary.Add("DP1", $dynParam1)
return $paramDictionary
}
}
}
For more information, see RuntimeDefinedParameter.
Switch parameters
Switch parameters are parameters with no parameter value. They're effective only when they're used and have only one effect.
For example, the NoProfile parameter of powershell.exe is a switch parameter.
To create a switch parameter in a function, specify the Switch
type in the
parameter definition.
For example:
Param([Switch]<ParameterName>)
Or, you can use an another method:
Param(
[Parameter(Mandatory=$false)]
[Switch]
$<ParameterName>
)
Switch parameters are easy to use and are preferred over Boolean parameters, which have a more difficult syntax.
For example, to use a switch parameter, the user types the parameter in the command.
-IncludeAll
To use a Boolean parameter, the user types the parameter and a Boolean value.
-IncludeAll:$true
When creating switch parameters, choose the parameter name carefully. Be sure that the parameter name communicates the effect of the parameter to the user. Avoid ambiguous terms, such as Filter or Maximum that might imply a value is required.
ArgumentCompleter attribute
The ArgumentCompleter attribute allows you to add tab completion values to a specific parameter. Like DynamicParameters, the available values are calculated at runtime when the user presses Tab after the parameter name.
To add an ArgumentCompleter attribute, you need to define a script block that will determine the values. The script block must take the following parameters in the order specified below. The parameter's names don't matter as the values are provided positionally.
The syntax is as follows:
Param(
[Parameter(Mandatory)]
[ArgumentCompleter({
param ($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter)
# Perform calculation of tab completed values here.
})]
)
ArgumentCompleter script block
The script block parameters are set to the following values:
$commandName
(Position 0) - This parameter is set to the name of the command for which the script block is providing tab completion.$parameterName
(Position 1) - This parameter is set to the parameter whose value requires tab completion.$wordToComplete
(Position 2) - This parameter is set to value the user has provided before they pressed Tab. Your script block should use this value to determine tab completion values.$commandAst
(Position 3) - This parameter is set to the Abstract Syntax Tree (AST) for the current input line. For more information, see Ast Class.$fakeBoundParameter
(Position 4) - This parameter is set to a hashtable containing the$PSBoundParameters
for the cmdlet, before the user pressed Tab. For more information, see about_Automatic_Variables.
The ArgumentCompleter script block must unroll the values using the
pipeline, such asForEach-Object
, Where-Object
, or another suitable method.
Returning an array of values causes PowerShell to treat the entire array as
one tab completion value.
The following example adds tab completion to the Value parameter. If no
$Type
is specified, fruits and vegetables are returned. If a $Type
is
specified, only values for the type are specified. In addition, the -like
operator ensures that if the user types the following command and uses
Tab completion, only Apple is returned.
Test-ArgumentCompleter -Type Fruits -Value A
function Test-ArgumentCompleter {
[CmdletBinding()]
param (
[Parameter(Mandatory)]
[ValidateSet('Fruits', 'Vegetables')]
$Type,
[Parameter(Mandatory)]
[ArgumentCompleter( {
param ( $commandName,
$parameterName,
$wordToComplete,
$commandAst,
$fakeBoundParameters )
$possibleValues = @{
Fruits = @('Apple', 'Orange', 'Banana')
Vegetables = @('Tomato', 'Squash', 'Corn')
}
if ($fakeBoundParameters.ContainsKey('Type'))
{
$possibleValues[$fakeBoundParameters.Type] | Where-Object {
$_ -like "$wordToComplete*"
}
}
else
{
$possibleValues.Values | ForEach-Object {$_}
}
} )]
$Value
)
}
See also
about_Functions_Advanced_Methods