Search notes:

PowerShell: Function and script parameters

In PowerShell, the declaration of parameters is similar in functions and in PowerShell scripts. A central role when declaring parameters is held by
This page tries to demonstrate some usages of $args and the param statement.

Not explicitly named parameters

It's possible to define a function that does not explicitly name its parameters. The values of the parameters can then be accessed within the function using the $args array.
This is similar to the @_ variable that stores the values that are passed to a Perl sub.
function add {
  $args[0] + $args[1]
}

$sum = add 19 23
write-output "sum is $sum"
#
# sum is 42

$sum = add "foo" "bar"
write-output "sum is $sum"
#
# sum is foobar
Github repository about-powershell, path: /language/statement/function/parameters/args.ps1

Named parameters

The parameters can be given a name so as to make life easier for the programmer.
function add($s1, $s2) {
  $sum = $s1 + $s2
  return $sum
}

write-host The sum is (add 19 23)
# The sum is 42
Github repository about-powershell, path: /language/statement/function/parameters/named.ps1

Constrained types

The types of the parameters can be constrained to make sure that the function gets what it expects.
function add ([int]$param_1, [int]$param_2) {
  $param_1 + $param_2
}

$sum = add 19 23
write-output "sum is $sum"
#
# sum is 42


#  $sum = add "foo" "bar"
#
#  Because add takes typed parameter, trying to
#  invoke add with strings resultes in the following
#  error:
#     Cannot process argument transformation on parameter 'param_1'.
#     Cannot convert value "foo" to type "System.Int32".
#     Error: "Input string was not in a correct format.
#

Github repository about-powershell, path: /language/statement/function/parameters/typed.ps1

The param keyword

The parameters can be listed more explicitly within a param block:
function add {

  #
  # Parameters can also be specified more explicitely
  # within the param() statement:
  #

    param (
        [int] $param_1,
        [int] $param_2
    )

    $param_1 + $param_2
}

$sum = add 19 23
write-output "sum is $sum"
Github repository about-powershell, path: /language/statement/function/parameters/param.ps1
With the exception of a using statement and comments (including #require), the param(…) block must be the first statement in a script or function in order to work (as I found out the hard way when I got an error message when I used set-strictMode before param in a script).
A function becomes advanced if the param keyword is prepended with [cmdletBinding()].
A param block is not permitted in class methods.

Parameter attributes

A special feature of the param statement is that it allows to «annotate» a parameter with attributes. These attributes are enclosed within brackets:
param (
    [parameter(mandatory=$true)]
    [string[]                  ]
    [validateCount(2,9)        ]
    $someParameter
  ,
    [ … ]
    $anotherParameter ..
)
The list of available attributes includes
parameter(…) for example parameter(mandatory=$true)
alias('xyz')
allowNull()
allowEmptyString()
allowEmptyCollection()
supportsWildcards() wildcards
validateCount(minElemCnt, maxElemCnt)
validateDrive('env')
validateLength(minStringLen, maxStringLen)
validatePattern(regExp) regular expressions
validateRange(valMin, valMax) (numerical?) value must be in given range
validateScript( { statement(s) } )
validateSet( 'foo', 'bar', 'baz' ) Value must be one of the explicitly given elements in the list
validateNotNull() Value must not be $null
validateNotNullOrEmpty()
The names of these atttributes are type accelerators.
An interesting benefit of annotating a parameter with validateSet is that it allows to «cycle through» the listed values with the tabulator (tab-completion) when entering the respective parameter.

Default values

A parameter can be declared with a default value which is used if the parameter is not explicitly given a value when the function is invoked:
function saySomething {

   param(
      [string] $text = 'hello world'
   )

   write-host $text
}

saySomething
saySomething 'good bye'
Github repository about-powershell, path: /language/function/parameter/default-value.ps1

Shift parameters

Powershell does not have a shift statement like other shells.
However it's possible to shift an array ($ary) with
Here's a demonstration of such a «shift»
function lispy {
   $op, $elems = $args

   invoke-expression ($elems -join $op)
}

lispy '+' 10 3 2
lispy '*' 10 3 2
lispy '-' 10 3 2
lispy '/' 10 3 2
Github repository about-powershell, path: /language/statement/function/parameters/shift.ps1
See also assigning an array to an array.

Turn a function into a cmdlet

param() can be prefixed with [cmdletBinding()] which causes the corresponding function to turn into a cmdLet, thus adding common parameters (such as -verbose or -errorAction]) automatically to the function/cmdlet:
function i-am-a-cmdlet {
   [cmdletBinding()]
    param (
      [string] $text
    )
  
   write-host     $text
   write-verbose "hello, I am a cmdlet"
    
}
This function/cmdlet can now be invoked with common parameters, for example like so:
i-am-a-cmdlet -verbose

Let PowerShell describe a function's parameters

get-command cmdName returns a System.Management.Automation.FunctionInfo object whose member Parameters is a collection of System.Management.Automation.ParameterMetadata objects which describe the parameters of a command, such as the function mkdir. The following example prints each parameter's name, abbreviation and data type:
$params = (get-command mkdir).parameters

foreach ($param in $params.keys) {
     $paramMeta = $params[$param]
    '{0,-20} {1,-6} {2}' -f $paramMeta.name, $paramMeta.aliases[0], $paramMeta.parameterType
}
#
# Path                        System.String[]
# Name                        System.String
# Value                       System.Object
# Force                       System.Management.Automation.SwitchParameter
# Credential                  System.Management.Automation.PSCredential
# Verbose              vb     System.Management.Automation.SwitchParameter
# Debug                db     System.Management.Automation.SwitchParameter
# ErrorAction          ea     System.Management.Automation.ActionPreference
# WarningAction        wa     System.Management.Automation.ActionPreference
# InformationAction    infa   System.Management.Automation.ActionPreference
# ErrorVariable        ev     System.String
# WarningVariable      wv     System.String
# InformationVariable  iv     System.String
# OutVariable          ov     System.String
# OutBuffer            ob     System.Int32
# PipelineVariable     pv     System.String
# WhatIf               wi     System.Management.Automation.SwitchParameter
# Confirm              cf     System.Management.Automation.SwitchParameter
# UseTransaction       usetx  System.Management.Automation.SwitchParameter
Github repository about-PowerShell, path: /language/function/parameter/info.ps1
Alternatively, a «real» pipeline can be uses to get more or less the same information:
PS C:\> (get-command mkdir).parameters.values | select-object name, parameterType, switchParameter, aliases
See also Querying meta info about a command

Script parameters

The following PowerShell script uses the same technique to declare parameters as in scripts:
param (
   [parameter(mandatory=$true)] [alias('tx')] [string] $text,
                                              [int   ] $optional,
                                              [switch] $flag
)

write-host "text     = $text"
write-host "optional = $optional"
write-host "flag     = $flag"
write-host ""
Github repository about-powershell, path: /language/statement/function/parameters/script.ps1
The following examples are all valid invocations of the script.
.\script.ps1     abc
.\script.ps1     def      91 
.\script.ps1     ghi      37 -flag
.\script.ps1     jkl      19 -f
.\script.ps1 -tx mno      28
.\script.ps1 -tx pqr -opt 48
…
The script cannot be invoked like so:
.\script
.\script abc def
.\script ghi  99 $true
.\script -foo bar
…

Parameter sets

Each parameter set must have at least one parameter that is not a member of any other parameter set, see also here and Param(Parameter(ParameterSetName=…).

TODO

Should this page be merged with PowerShell function parameters?

See also

Passing parameters by reference.
Parameter splatting
The function statement
Switch parameters

Index