{"id":12431,"date":"2011-10-11T00:01:00","date_gmt":"2011-10-11T00:01:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2011\/10\/11\/use-powershell-parameter-attributes-to-avoid-errors\/"},"modified":"2011-10-11T00:01:00","modified_gmt":"2011-10-11T00:01:00","slug":"use-powershell-parameter-attributes-to-avoid-errors","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/use-powershell-parameter-attributes-to-avoid-errors\/","title":{"rendered":"Use PowerShell Parameter Attributes to Avoid Errors"},"content":{"rendered":"<p><strong>Summary:<\/strong> Use Windows PowerShell parameter attributes to avoid input errors in a function.<\/p>\n<p>&nbsp;<\/p>\n<p>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&nbsp; ime to head out to a really neat hardware store and gaze longingly at the hand planes.<\/p>\n<p>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&rsquo;s <a href=\"http:\/\/blogs.technet.com\/b\/heyscriptingguy\/archive\/2011\/10\/10\/cool-powershell-game-teaches-cmdlet-names.aspx\">Cool PowerShell Game Teaches Cmdlet Names<\/a>&nbsp;post could stand a bit of improvement. I definitely agree.<\/p>\n<p>In today&rsquo;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&rsquo;s script it would be possible to get a divide-by-zero error if you ran the script with the wrong number for the&nbsp; 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 <b>New-CmdletPuzzle <\/b>function is shown here.<\/p>\n<p style=\"padding-left: 30px\">function New-CmdletPuzzle<\/p>\n<p style=\"padding-left: 30px\">{<\/p>\n<p style=\"padding-left: 30px\">&nbsp;Param(<\/p>\n<p style=\"padding-left: 30px\">&nbsp; [Parameter(Position=0,<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; HelpMessage=&#8221;A number between 2 and 7&#8243;)]<\/p>\n<p style=\"padding-left: 30px\">&nbsp; [alias(&#8220;Level&#8221;)]<\/p>\n<p style=\"padding-left: 30px\">&nbsp; [ValidateRange(2,7)]<\/p>\n<p style=\"padding-left: 30px\">&nbsp; [int]$difficulty = 4<\/p>\n<p style=\"padding-left: 30px\">&nbsp;) #end param<\/p>\n<p style=\"padding-left: 30px\">&nbsp;$array = @()<\/p>\n<p style=\"padding-left: 30px\">&nbsp;$array = Get-Command -CommandType cmdlet |<\/p>\n<p style=\"padding-left: 30px\">&nbsp;ForEach-Object { $_.name.tostring() }<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">&nbsp;Foreach($cmdlet in $array)<\/p>\n<p style=\"padding-left: 30px\">&nbsp;{<\/p>\n<p style=\"padding-left: 30px\">&nbsp; $rndChar = get-random -InputObject ($cmdlet.tochararray()) `<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -count ($cmdlet.length\/$difficulty)<\/p>\n<p style=\"padding-left: 30px\">&nbsp; foreach($l in $rndchar)<\/p>\n<p style=\"padding-left: 30px\">&nbsp; {<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp; $cmdlet = $cmdlet.Replace($l,&#8221;_&#8221;)<\/p>\n<p style=\"padding-left: 30px\">&nbsp; }# end foreach l<\/p>\n<p style=\"padding-left: 30px\">&nbsp; $cmdlet<\/p>\n<p style=\"padding-left: 30px\">&nbsp;} #end foreach cmdlet<\/p>\n<p style=\"padding-left: 30px\">}<br \/>#end function New-CmdletPuzzle<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p>The two changes I made to yesterday&rsquo;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 <b>function<\/b><i> <\/i>keyword, provide a function name, and place the code in a pair of braces (curly&nbsp; rackets).<\/p>\n<p>The <b>param<\/b><i> <\/i>keyword tells the function to expect a value from the command line. I use the <b>parameter<\/b><i> <\/i>attribute to create a parameter in position 0 and assign a <b>helpmessage<\/b><i> <\/i>value as well. Here is the first part of the <b>param<\/b><i> <\/i>statement:<\/p>\n<p style=\"padding-left: 30px\">Param(<\/p>\n<p style=\"padding-left: 30px\">&nbsp; [Parameter(Position=0,<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; HelpMessage=&#8221;A number between 2 and 7&#8243;)]<\/p>\n<p>In addition, I decided to create an alias for the input parameter. To do this I use the <b>alias<\/b><i> <\/i>attribute:<\/p>\n<p style=\"padding-left: 30px\">[alias(&#8220;Level&#8221;)]<\/p>\n<p>The most important attribute for my <b>New-CmdletPuzzle <\/b>is the <b>validaterange<\/b><i> <\/i>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&nbsp; rguments to the attribute. Here is <b>validaterange<\/b><i> <\/i>attribute.<\/p>\n<p style=\"padding-left: 30px\">[ValidateRange(2,7)]<\/p>\n<p>If I supply a value to the function that is outside the allowed range specified by the <b>validaterange<\/b><i> <\/i>attribute, a nonterminating error occurs. A sample error is shown here:<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/6320.hsg-10-11-11-1.png\"><img decoding=\"async\" style=\"border: 0px\" title=\"Image of sample error\" alt=\"Image of sample error\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/6320.hsg-10-11-11-1.png\" \/><\/a><\/p>\n<p>The last thing I do is specify a default value for the <i>difficulty <\/i>parameter. In addition, I use a type constraint to ensure the value is an integer. This line of code is shown here:<\/p>\n<p style=\"padding-left: 30px\">[int]$difficulty = 4<\/p>\n<p>The entire parameter section is shown here:<\/p>\n<p style=\"padding-left: 30px\">Param(<\/p>\n<p style=\"padding-left: 30px\">&nbsp; [Parameter(Position=0,<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; HelpMessage=&#8221;A number between 2 and 7&#8243;)]<\/p>\n<p style=\"padding-left: 30px\">&nbsp; [alias(&#8220;Level&#8221;)]<\/p>\n<p style=\"padding-left: 30px\">&nbsp; [ValidateRange(2,7)]<\/p>\n<p style=\"padding-left: 30px\">&nbsp; [int]$difficulty = 4<\/p>\n<p style=\"padding-left: 30px\">&nbsp;) #end param<\/p>\n<p>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&nbsp; arameter is essentially mandatory because a value is always used for the parameter. I can use the <b>level<\/b><i> <\/i>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.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/3240.hsg-10-11-11-2.png\"><img decoding=\"async\" style=\"border: 0px\" title=\"Image of command and associated output\" alt=\"Image of command and associated output\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/3240.hsg-10-11-11-2.png\" \/><\/a><\/p>\n<p>The file created by the previous command is shown in the following image.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/1754.hsg-10-11-11-3.png\"><img decoding=\"async\" style=\"border: 0px\" title=\"Image of file created by command\" alt=\"Image of file created by command\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/1754.hsg-10-11-11-3.png\" width=\"421\" height=\"759\" \/><\/a><\/p>\n<p>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&hellip;see you tomorrow. Until then, have a great day.<\/p>\n<p>&nbsp;<\/p>\n<p>I invite you to follow me on <a href=\"http:\/\/bit.ly\/scriptingguystwitter\" target=\"_blank\">Twitter<\/a> and <a href=\"http:\/\/bit.ly\/scriptingguysfacebook\">Facebook<\/a>. If you have any questions, send email to me at <a href=\"mailto:scripter@microsoft.com\" target=\"_blank\">scripter@microsoft.com<\/a>, or post your questions on the <a href=\"http:\/\/bit.ly\/scriptingforum\" target=\"_blank\">Official Scripting Guys Forum<\/a>. See you tomorrow. Until then, peace.<\/p>\n<p><b>Ed Wilson, Microsoft Scripting Guy<\/b><\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Summary: Use Windows PowerShell parameter attributes to avoid input errors in a function. &nbsp; 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 [&hellip;]<\/p>\n","protected":false},"author":596,"featured_media":87096,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[69,3,4,21,45],"class_list":["post-12431","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-functions","tag-scripting-guy","tag-scripting-techniques","tag-string-manipulation","tag-windows-powershell"],"acf":[],"blog_post_summary":"<p>Summary: Use Windows PowerShell parameter attributes to avoid input errors in a function. &nbsp; 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 [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/12431","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/users\/596"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/comments?post=12431"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/12431\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media\/87096"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media?parent=12431"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=12431"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=12431"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}