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.

Image of logo

     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:

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:

Image of command output

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.

Image of command output

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:

Image of command output

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