Problem solve Get help with specific problems with your technologies, process and projects.

Understanding Windows PowerShell function parameters

Parameters in Windows PowerShell can help admins better customize their functions, leading to improved input testing and more extensible commands.

The PowerShell parameter is a fundamental component of any script. A parameter is a way that developers enable script users to provide input at runtime. If a PowerShell script's behavior needs to change in some way, a parameter provides an opportunity to do so without changing the underlying code.

Parameters enable developers to build reusable PowerShell scripts that require little code maintenance and extensibility if built correctly.

In this article, you'll learn how to create scripts and PowerShell function parameters, how to use them and some best practices for building parameters.

Defining parameters

Parameters can be created for scripts and functions and are always enclosed in a param block defined with the param keyword, followed by opening and closing parentheses.

param()

Inside of that param block contains one or more parameters defined by -- at their most basic -- a single variable as shown below.

param(
    $Parameter1
)

However, to ensure the parameter accepts only the type of input you need and will support other features in the future, best practices dictate assigning a type to the parameter and including a [Parameter()] block. In the example below, you can see a parameter that accepts only objects of type string.

param(
    [Parameter()]
    [string]$Parameter1
)

Additional parameters can be added in the same manner by separating them with a comma, as seen in the example below.

param(
    [Parameter()]
    [string]$Parameter1,

    [Parameter()]
    [string]$Parameter2
)

Write-Host "Parameter 1 value is $Parameter1"
Write-Host "Parameter 2 value is $Parameter2"

Named parameters

One way to use PowerShell function parameters in a script is via parameter name -- this method is called named parameters. When calling a script or function via named parameters, use the entire name of the parameter.

For example, perhaps the example param block above is stored in a PowerShell script called foo.ps1. If you need to provide values to the Parameter1 and Parameter2 parameters using named parameters, you'd do so in the manner below. Notice that each parameter's full name is used, followed by the value being passed to it.

./foo.ps1 -Parameter1 'somevalue' -Parameter2 'someothervalue'

When you run this script, you'll see a similar output to the one below, which replaces each parameter variable with the value passed at runtime.

Parameter1 somevalue

Positional parameters

Another way to use parameters is to pass values by position rather than by name. When you pass a parameter value by position, the name of the parameter isn't used. PowerShell instead matches up the values for each parameter by the position it holds in the command.

Using the previous example of the foo.ps1 script, the values for Parameter1 and Parameter2 can be passed using the positional parameters below. The parameter names aren't used. Instead, PowerShell knows Parameter1 was defined above Parameter2 in the script and automatically matches up the values in order.

./foo.ps1 'somevalue' 'someothervalue'

Running this script using positional parameters ends up with the same output result.

Parameter2 someothervalue

In the above example, both the Parameter1 and Parameter2 were defined as string types, but this isn't the only type you can use. You can use any type in the .NET class library.

Switch parameters

Another parameter you can use is the switch parameter. This parameter is used for binary or Boolean values to indicate "on" or "off." It's defined with the [switch] type.

Continuing to use the example with two parameters, add a switch parameter. Perhaps you'd like to display the output of Parameter2 only if explicitly specified. To ensure the value of Parameter2 is displayed, add a switch parameter called DisplayParameter2Value, as shown below.

Once the switch parameter is in place, you can make a logic decision in your code by inserting an if/then construct to only run code if the switch parameter is present.

param(
    [Parameter()]
    [string]$Parameter1,

    [Parameter()]
    [string]$Parameter2,

    [Parameter()]
    [switch]$DisplayParameter2Value
)

Write-Host "Parameter 1 value is $Parameter1"
if ($DisplayParameter2Value.IsPresent) {
    Write-Host "Parameter 2 value is $Parameter2"
}

You now have the option to display the value of Parameter2 -- or not -- as you can see below.

Display Parameter 2 value

Splatting

The above example only has three parameters. Passing values to those parameters doesn't extend too far to the right. But what if you have 10 or more parameters? And what if those parameters have long names? In that case, you need do so some splatting.

Splatting is a term that describes setting up parameters for a script or function before you run a command. Throughout this article, you've been defining and passing values to parameters at runtime. This can be problematic when you have a set of parameters that looks something like this:

param(
    [Parameter()]
    [string]$Parameter1,

    [Parameter()]
    [string]$Parameter2,

    [Parameter()]
    [switch]$DisplayParameter2Value,

    [Parameter()]
    [string]$Parameter3,

    [Parameter()]
    [string]$Parameter4,

    [Parameter()]
    [string]$Parameter5,

    [Parameter()]
    [string]$Parameter6,

    [Parameter()]
    [string]$Parameter7
)

Write-Host "Parameter 1 value is $Parameter1"
if ($DisplayParameter2Value.IsPresent) {
    Write-Host "Parameter 2 value is $Parameter2"
}
Write-Host "Parameter 3 value is $Parameter3"
Write-Host "Parameter 4 value is $Parameter4"
Write-Host "Parameter 5 value is $Parameter5"
Write-Host "Parameter 6 value is $Parameter6"
Write-Host "Parameter 7 value is $Parameter7"

If you need to pass values via named parameters in this new example, the command would extend far beyond a reasonable length to the right.

./foo.ps1 -Parameter1 'somevalue' -Parameter2 'someothervalue' -Parameter3 'somevalue' -Parameter4 'somevalue' -Parameter5 'somevalue' -Parameter6 'somevalue' -Parameter7 'somevalue' -DisplayParameter2Value

Instead of scrolling to the right, you could define the parameter values in a separate step using a hashtable, as shown below. Each parameter value can be lined up nicely and it's much easier to see what parameters are being used.

Once the hashtable is created, you can pass all the parameters to the script or command by just specifying the name of the hashtable preceded by an @ character.

$parameters = @{
    Parameter1             = 'somevalue'
    Parameter2             = 'someothervalue'
    Parameter3             = 'somevalue'
    Parameter4             = 'somevalue'
    Parameter5             = 'somevalue'
    Parameter6             = 'somevalue'
    Parameter7             = 'somevalue'
    DisplayParameter2Value = $true
}

PS> ./foo.ps1 @parameters

PowerShell parameter attributes

Recall in the "Defining parameters" section above I mentioned the [Parameter()] construct was optional but recommended? This section is one of those reasons.

There are many ways you can manipulate parameter behavior, known as parameter attributes. You can do things such as enforce that a specific parameter is used, ensure the values passed to a parameter are part of a specific set and match a regular expression. Microsoft provides a comprehensive list of advanced parameters, but to start, you only need to know the most common ones.

Mandatory parameters

It's common to have one or more PowerShell function parameters that must be used when a script is executed. In PowerShell-speak, that parameter enforcement is called a mandatory parameter. When you make a parameter mandatory, the script or function can't run without it. Even if you forget to use the parameter, PowerShell will interactively prompt you for the value.

Consider the switch parameter example. The only difference below is that Parameter1 was made mandatory by using the keyword in the [Parameter()] construct.

param(
    [Parameter(Mandatory)]
    [string]$Parameter1,

    [Parameter()]
    [string]$Parameter2,

    [Parameter()]
    [switch]$DisplayParameter2Value
)

Write-Host "Parameter 1 value is $Parameter1"
if ($DisplayParameter2Value.IsPresent) {
    Write-Host "Parameter 2 value is $Parameter2"
}

Before assigning the Parameter1 to be mandatory, this script could have been executed like this without a problem. The value of Parameter1 would simply be empty.

./foo.ps1 -Parameter2 someothervalue

You can see what happens once the parameter is made mandatory below. PowerShell won't allow the script to run and prompts you for a value.

Mandatory parameter

Parameter validation

Finally, ensure values passed to parameters are exactly what you'd expect. It's best practice to limit the potential of someone passing in an unexpected value to a parameter. You have various parameter validation options at your disposal to limit the values used in parameters. For a complete list, refer to advanced parameters in Microsoft's documentation.

Perhaps you know that Parameter1 should only ever be one of two values: foo and bar. You want to ensure that the value of Parameter1 will never be anything other than those values. In that case, you can use a parameter validation attribute called ValidateSet.

All parameter validation attributes are defined above the parameter name, as shown below. In this instance, ValidateSet was assigned to Parameter1. This parameter validation attribute accepts an array of values. In the below example, that's 'foo','bar'.

param(
    [Parameter(Mandatory,)]
    [ValidateSet('foo','bar')]
    [string]$Parameter1,

    [Parameter()]
    [string]$Parameter2,

    [Parameter()]
    [switch]$DisplayParameter2Value
)

Write-Host "Parameter 1 value is $Parameter1"
if ($DisplayParameter2Value.IsPresent) {
    Write-Host "Parameter 2 value is $Parameter2"
}

If you were to try to pass a value other than foo or bar to Parameter1, you'd get an error like this:

Parameter1 value error

Parameter validation attributes are a great way to limit what can be used.

Dig Deeper on Enterprise infrastructure management

Join the conversation

1 comment

Send me notifications when other members comment.

Please create a username to comment.

ParameterSetName  section can use some additional explanation.
Or, maybe, it's just stupid me.
Cancel

-ADS BY GOOGLE

SearchServerVirtualization

SearchCloudComputing

SearchSQLServer

SearchEnterpriseDesktop

SearchVirtualDesktop

Close