Summary: Microsoft Scripting Guy, Ed Wilson, wraps up the 2014 Winter Scripting Games and talks about parameter validation.
Weekend Scripter: Parameter Validation
Microsoft Scripting Guy, Ed Wilson, is here. Today, I'm playing with my new Surface Pro 2 device. It came with a year of free Skype and two years of 200 GB storage on OneDrive. WooHoo! It is great. I love that the Surface Pro 2 is so fast and so robust. I was really surprised and happy when the Scripting Wife got it for me. Cool.
Note This is the final post in a series in which I talk about things I noticed whilst grading submissions for the
2014 Winter Scripting Games. In case you missed the previous episodes:
- 2014 Winter PowerShell Scripting Games Wrap Up #1
Talked about best practices for using aliases and for formatting of Windows PowerShell scripts. - 2014 Winter PowerShell Scripting Games Wrap Up #2
Talked about the need for and the use of structured error handling. - 2014 Winter PowerShell Scripting Games Wrap Up #3
Talked about using standard Windows folders from within Windows PowerShell scripts. - 2014 Winter PowerShell Scripting Games Wrap Up #4
Talked about using the Write-Verbose and Write-Error streams in Windows PowerShell scripts. - 2014 Winter PowerShell Scripting Games Wrap Up #5
Talked about cleaning up Windows PowerShell script by using the switch statement.
In today’s post, I’ll discuss adding robustness to Windows PowerShell scripts by using parameter validation.
What are parameter validation attributes?
Glenn Sizemore wrote a great introduction to Windows PowerShell parameter validation attributes in his blog post, Simplify Your PowerShell Script with Parameter Validation. It is a good overview. I also talked about using a ValidatePattern parameter attribute in Validate PowerShell Parameters before Running the Script. That post provides a good example of using a regular expression pattern to validate parameter input.
The whole point of using parameter validation attributes is that it does the following:
- Simplifies Windows PowerShell scripting by using built-in capabilities
- Makes your Windows PowerShell script easier to read and easier to understand
- Makes the script more robust by checking permitted input values
- Simplifies script error handling
About parameter validation attributes
There are a number of parameter validation attributes. They are documented in about_Functions_Advanced_Parameters in the TechNet Library. The following table lists the parameter validation attributes.
Validation Attribute | Meaning |
AllowNull | Permits a null value for a Mandatory parameter |
AllowEmptyString | Permits an empty string, “”, as a value for a mandatory parameter |
AllowEmptyCollection | Permits an empty collection, @() for the value of a mandatory parameter |
ValidateCount | Specifies the minimum and the maximum values that a parameter accepts |
ValidateLength | Specifies the minimum and the maximum number of characters in a value supplied to a parameter |
ValidatePattern | Specifies a regular expression pattern a value must match |
ValidateRange | Specifies a range of values for a parameter value |
ValidateScript | Code raises an error if code evaluates to “false” |
ValidateSet | Specifies that the value for a parameter must be a member of the defined set |
ValidateNotNull | Generates an error if the value is null |
ValidateNotNullOrEmpty | Generates an error if the parameter value is used in a function call and is null, an empty string or an empty array |
A practical example
In the following function, the input must be a member of a particular set. The set is defined in a variable called $myset and an if/else construction checks input to see if it is a member of that set. If it is, the input is valid. If it is not, an error message appears, and the permissible values are displayed. This is a useful script, and it is a nice check on the input values.
Function My-Parameters
{
Param ($myinput)
$myset = "red","blue","green","orange"
if($myset -contains $myinput)
{Write-Output "The input is valid"}
else
{ throw "The input is not valid. It must be a member of $myset" }
}
After I load the function, I call the function and pass a couple values. The values are members of the $myset set, and therefore, it is valid input. When I pass the value almond, however, an error is thrown. This is shown in the image that follows:
I can rewrite the previous script to use parameter validation. To do this, I use the [ValidateSet()] attribute:
Function Use-ParameterSetValidation
{
Param(
[ValidateSet("red","blue","green","orange")]
[string]$myInput)
Write-Output "The input is valid"
}
Not only is the script a lot cleaner, but it is much less typing. In addition, the script is easier to read because I do not need to weave through the if/else statement and the throw statement. But more than that, if I run the function in the Windows PowerShell ISE, I also gain IntelliSense. In this way, it makes it very difficult to choose the wrong value. In fact, I have to deliberately ignore the IntelliSense to enter a false value. The following image illustrates the free IntelliSense I gain when I implement the ValidateSet parameter attribute.
Even though I did not wire up a throw statement, if I ignore the IntelliSense and I supply the wrong value for the parameter, an error occurs. In addition, like in my previous example where I displayed the contents of the $myset variable to show the permissible values, Windows PowerShell supplies the permissible values for the set. This is shown in the following image:
Join me tomorrow when I begin a series about using Windows PowerShell with Microsoft Surface RT, Microsoft Surface Pro, and Microsoft Surface Pro 2. It will be some fun stuff.
I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.
Ed Wilson, Microsoft Scripting Guy