In a previous article on customizing Windows PowerShell, I explained how one of PowerShell's strongest traits is its extensibility
Requires Free Membership to View
What's the difference you ask? Production-quality functions make an effort to test input and do a solid job of dealing with errors while still providing informational output. Generally when using a function for production, you want to know if it breaks -- and you definitely want to know why. Other languages require you to design your own parameter and error handlers. Lucky for us, Windows PowerShell has much of this functionality built in.
PowerShell parameters
When we talk about functions in Windows PowerShell, we need to consider three things: input, output and errors. This article will focus primarily on input, also known as parameters. PowerShell has many options when it comes to dealing with parameters, and they can be passed in one of three ways:
- Positional parameters
PowerShell creates a variable called $args that is an array of values passed to the function. Each value passed to the function gets added to this array starting at 0.Example:
function foo
{
Write-Host $args[0] $args[1]
}
foo "This is parameter 1" "This is parameter 2" - Named parameters
PowerShell input parameters can also be named, which means they are passed by name and the values are placed in the corresponding variable.Example (notice the parameters are reversed when the function is called,
but the values are returned correctly):
function foo
{
Param($param1,$param2)
Write-Host $param1 $param2
}foo -param2 "This is parameter 2" -param1 "This is
parameter 1" - Splatting
This is perhaps the most unusual way to pass parameters in PowerShell. It involves creating an array or hash table to pass the parameters as a group to the function. This allows you to dynamically create the parameters throughout your script and then call the function when you're ready.Example:
function foo
{
Param($param1,$param2)
Write-Host $param1 $param2
}Create Hash table
$blah = @{"Param1"="This is parameter 1";
"Param2"="This is parameter 2"}# Pass hash table to function
foo @Blah
PowerShell parameter attributes
- Mandatory -- PowerShell parameters are optional by default, but if you have a
parameter that you know is required you can use this attribute to force users to pass the
parameter. If they do not pass the parameter, PowerShell will let them know they did something
wrong and force them to provide a value for the function to work properly.
Example:
function foo
{
Param(
[Parameter(Mandatory=$True)]
$param1
)
Write-Host $param1
} - ParameterSetName -- We often need to pass a group of parameters together
(usually because otherwise something will break). For example, if you had a function that retrieved
an Active Directory object, you'd need to know if it was a user or a computer account:
function Get-ADObject
{
Param(
[Parameter(Mandatory=$True,
ParameterSetName="User")]
$User,[Parameter(Mandatory=$True,
ParameterSetName="Computer")]
$Computer
)
$PScmdlet.ParameterSetName
}Get-ADObject --# This will throw an error because no
parameters passed
Get-ADObject –user "joe" # Will return 'User'
Get-ADObject –Computer "joe" # Will return 'Computer'
Get-ADObject –User "joe" –Computer "joe" # Will return
an error - ValueFromPipeline -- This tells the function that value in this specific
parameter can be passed via the pipeline. This is determined by the "type" of the value being piped
in.
Example:
function Get-ADUserObject
{
Param(
[Parameter(ValueFromPipeline=$true)]
$User,
)
Process
{
$User
}
}
}
$ListofUsers | Get-ADUserObject - ValueFromPipelineByPropertyName -- This is similar to ValueFromPipeline
attribute, but instead of using "type" it uses the property name of the incoming object. For
example, if you had a user object with a property called UserName, you would do this:
function Get-ADUserObject
{
Param(
[Parameter(ValueFromPipeline
ByPropertyName=$true)]
$Username,
)
Process
{
$UserName
}
}
$ListofUserObjects | Get-ADUserObject - HelpMessage -- This allows you to add a help message for the user. If they
were to call your function without a specific mandatory property, this could explain to the user
what they need to pass:
function Get-ADComputerObject
{
Param(
[Parameter(Mandatory=$True,HelpMessage=
"Enter computer name.")]
$ComputerName,
)
$ComputerName
}
The info above should help you get started with writing production-quality functions, but keep in mind that this is only the tip of the iceberg. To learn the full gambit of what PowerShell functions have to offer, visit the Script Center at Microsoft TechNet.
Miss a column? Check out our Scripting School archive.
ABOUT THE AUTHOR
Brandon Shell has been in the IT industry since 1994. He started out as a PC tech and
general fix-it guy for numerous companies. In 2007, he joined the PowerShell MVP ranks, and Shell
has spent the past several years building his PowerShell knowledge and helping others build
theirs.
This was first published in August 2010
Enterprise Server Strategies for the CIO
Join the conversationComment
Share
Comments
Results
Contribute to the conversation