October 11th, 2011

Use PowerShell Parameter Attributes to Avoid Errors

Doctor Scripto
Scripter

Summary: Use Windows PowerShell parameter attributes to avoid input errors in a function.

 

Microsoft Scripting Guy Ed Wilson here. This week is great. The Scripting Wife and I are enjoying meeting Windows PowerShell luminaries. I am working with a group of IT pros to help them to learn Windows PowerShell, and the weather has been wonderful. I hope to get some  ime to head out to a really neat hardware store and gaze longingly at the hand planes.

Anyway, one of the students, who reads the Hey, Scripting Guy! Blog on a daily basis, commented that he thought that the script in yesterday’s Cool PowerShell Game Teaches Cmdlet Names post could stand a bit of improvement. I definitely agree.

In today’s article, I am going to modify the script from yesterday and turn it into a function. In addition, I am going to add parameter validation. For example, in yesterday’s script it would be possible to get a divide-by-zero error if you ran the script with the wrong number for the  ount. In addition, it is possible to receive an output of a continuous solid line if you were to change the input value to a one. To make it easy to use the code and to modify the difficulty of the puzzle, I will include a command-line parameter to allow for quickly changing the difficulty. The complete New-CmdletPuzzle function is shown here.

function New-CmdletPuzzle

{

 Param(

  [Parameter(Position=0,

             HelpMessage=”A number between 2 and 7″)]

  [alias(“Level”)]

  [ValidateRange(2,7)]

  [int]$difficulty = 4

 ) #end param

 $array = @()

 $array = Get-Command -CommandType cmdlet |

 ForEach-Object { $_.name.tostring() }

 

 Foreach($cmdlet in $array)

 {

  $rndChar = get-random -InputObject ($cmdlet.tochararray()) `

           -count ($cmdlet.length/$difficulty)

  foreach($l in $rndchar)

  {

   $cmdlet = $cmdlet.Replace($l,”_”)

  }# end foreach l

  $cmdlet

 } #end foreach cmdlet

}
#end function New-CmdletPuzzle

 

The two changes I made to yesterday’s script convert the inline script to a function and add a command-line parameter. To convert the script to a function, all I needed to do was use the function keyword, provide a function name, and place the code in a pair of braces (curly  rackets).

The param keyword tells the function to expect a value from the command line. I use the parameter attribute to create a parameter in position 0 and assign a helpmessage value as well. Here is the first part of the param statement:

Param(

  [Parameter(Position=0,

             HelpMessage=”A number between 2 and 7″)]

In addition, I decided to create an alias for the input parameter. To do this I use the alias attribute:

[alias(“Level”)]

The most important attribute for my New-CmdletPuzzle is the validaterange attribute. It limits the permissible values for the function. For this function, I do not want anyone to use a level less than 2 or greater than 7. To do this, I specify my minimum and maximum range as  rguments to the attribute. Here is validaterange attribute.

[ValidateRange(2,7)]

If I supply a value to the function that is outside the allowed range specified by the validaterange attribute, a nonterminating error occurs. A sample error is shown here:

Image of sample error

The last thing I do is specify a default value for the difficulty parameter. In addition, I use a type constraint to ensure the value is an integer. This line of code is shown here:

[int]$difficulty = 4

The entire parameter section is shown here:

Param(

  [Parameter(Position=0,

             HelpMessage=”A number between 2 and 7″)]

  [alias(“Level”)]

  [ValidateRange(2,7)]

  [int]$difficulty = 4

 ) #end param

That is it. When I run the function with no input parameters, it runs with a default value of 4. If I made the parameter mandatory, the function would ignore the default value and prompt. But when I have a default value assigned, it is always used unless it is overridden, so the  arameter is essentially mandatory because a value is always used for the parameter. I can use the level alias, and pipe the output as I would a regular Windows PowerShell cmdlet. The command and associated output for this are shown in the following image.

Image of command and associated output

The file created by the previous command is shown in the following image.

Image of file created by command

Well, that is enough playing around for one day. Join me tomorrow as I continue to explore string manipulation, and as I continue, my progression from script to function to…see you tomorrow. Until then, have a great day.

 

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

 

 

Author

The "Scripting Guys" is a historical title passed from scripter to scripter. The current revision has morphed into our good friend Doctor Scripto who has been with us since the very beginning.

0 comments

Discussion are closed.