Summary: Learn how to use Windows PowerShell parameter validation attributes to check parameters before running the script.
Hey, Scripting Guy! I have a problem that I think that you can help me with. I have created a Windows PowerShell script that allows Help Desk people to enter information about users such as the user’s telephone number. The idea is that when users call the Help Desk, the Help Desk technician updates the user’s information in Active Directory. We tried using a self-service portal to do this but the users were unable to perform that task correctly. When we requested a data dump from Human Resources (HR), we found that much of the information was incomplete. My problem is that the Help Desk people do not appear to enjoy doing this job and therefore they are sloppy. I need something to add to my script to ensure that the information is entered in the proper format. That is where you come in, I hope.
— HI
Hello HI, Microsoft Scripting Guy Ed Wilson here. Today is Scripting Guys Day! It does not mean that my boss will take me out for lunch, or even buy me flowers . However, it does mean that I intend to do what I want today (except for the three meetings I have, and the one report I have to generate). The things that I enjoy doing the most are answering email messages that are sent to Scripter@Microsoft.Com and hanging out on Twitter. The fun thing about being the Microsoft Scripting Guy is getting to answer questions and help people to become more effective in using Windows PowerShell to resolve real-world problems. Yep, yep, yep, that is what I am going to do today. Not only is it Scripting Guys Day but the date can be expressed as 1-11-11 (that is 31 in decimal) – now that ought to count for something.
As an aside, it is easy to perform numeric conversions using Windows PowerShell. To convert 11111 to decimal in Windows PowerShell, I use the static toInt16 method from the system.convert .NET Framework class. This is shown here.
PS C:\> [convert]::ToInt16(11111,2)
31
If on the other hand, I want to convert decimal 31 to binary, I use the ToString static method. This is seen here.
PS C:\> [convert]::ToString(31,2)
11111
By the way, I can convert 31 to hexadecimal by also using the toString static method. This time, I specify that I want base 16. This is seen here.
PS C:\> [convert]::ToString(31,16)
1f
In the past, I have written about retrieving input, and about validating input by using various mechanisms. Today, I want to look at using parameter validation attributes. I am going to make it easy and examine telephone numbers. I say make it easy because I recently talked about how to use regular expressions to validate telephone numbers. Refer to that article for the Regex pattern explanation. A basic parameter validation for telephone numbers is seen in the Test-ParameterPatternBasic.ps1 script.
Test-ParameterPatternBasic.ps1
Function Test-Parameters
{
Param(
[ValidatePattern(“\d{3}-\d{3}-\d{4}”)]
$phoneNumber
)
Write-host “The phone number $phoneNumber is valid”
} #end function Test-Parameters
Test-Parameters -phoneNumber 999-555-1212
The “trick” is to use the [ValidatePattern()] parameter validation attribute. Inside the () I place the regex pattern I want to use to validate the input value to the parameter. Here the regex pattern is “\d{3}-\d{3}-\d{4}”. That is the pattern that I copied from my previous Hey, Scripting Guy! Blog post. The pattern tells me that I am looking for three digits separated by a dash, followed by three digits, a dash, and four more digits. That is it.
As for placement of the [ValidatePattern(“\d{3}-\d{3}-\d{4}”)] attribute, it is placed before the parameter, but after the Param statement. I like to place them on their individual line in the script to ensure readability. Then the script runs, and a valid telephone number is submitted a message is displayed that the telephone number is valid. The cool thing is that the telephone number does not have to be enclosed in quotation marks. The output is seen in the following figure.
If a telephone number is submitted (or anything else that does not match the pattern previously described) an error will be generated. This error will describe the expected pattern, and is illustrated in the following figure. (I have highlighted the pattern portion of the error in yellow, and drawn an arrow to it. Normally, the error message would appear without these emendations.)
If the parameter is mandatory (as in the case of this script) I like to use the mandatory parameter attribute. When I do this, I also like to supply a help message that will be displayed if the function is called without supplying a value for the parameter. The revised script that uses the mandatory parameter attribute is seen here.
Test-ParameterPatternAdvanced.ps1
Function Test-Parameters
{
Param(
[Parameter(Mandatory=$true,
HelpMessage=”Enter a valid telephone number xxx-xxx-xxxx”)]
[ValidatePattern(“\d{3}-\d{3}-\d{4}”)]
$phoneNumber
)
Write-host “The phone number $phoneNumber is valid”
} #end function Test-Parameters
Test-Parameters -phoneNumber 111-555-1212
The only change to the script was adding the mandatory parameter attribute. This is seen here.
[Parameter(Mandatory=$true,
HelpMessage=”Enter a valid telephone number xxx-xxx-xxxx”)]
No commas are used to separate the two parameter validation attributes. Here the mandatory attribute and help message are a single command that is broken into two lines to display it on the blog. When the script is run, and the mandatory parameter is absent, a dialog appears (when running in Windows PowerShell ISE) with the help text listed below the prompt. This is seen in the following figure.
HI, that is all there is to using parameter validation attributes. Input week will continue tomorrow.
I invite you to follow me on Twitter or Facebook. If you have any questions, send email to me at scripter@microsoft.com or post them on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.
Ed Wilson, Microsoft Scripting Guy
0 comments