{"id":52943,"date":"2009-07-15T03:01:00","date_gmt":"2009-07-15T03:01:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2009\/07\/15\/hey-scripting-guy-how-can-i-verify-input-received-from-the-command-line\/"},"modified":"2009-07-15T03:01:00","modified_gmt":"2009-07-15T03:01:00","slug":"hey-scripting-guy-how-can-i-verify-input-received-from-the-command-line","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/hey-scripting-guy-how-can-i-verify-input-received-from-the-command-line\/","title":{"rendered":"Hey, Scripting Guy! How Can I Verify Input Received from the Command Line?"},"content":{"rendered":"<p>&nbsp;<img decoding=\"async\" class=\"nearGraphic\" title=\"Hey, Scripting Guy! Question\" border=\"0\" alt=\"Hey, Scripting Guy! Question\" align=\"left\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/q-for-powertip.jpg\" width=\"34\" height=\"34\"><\/p>\n<p class=\"MsoNormal\">I am the script writer at my company, and I have really been enjoying your articles on Windows PowerShell. I have begun the process of converting some of our old VBScripts to Windows PowerShell, and all of my new scripts are written in Windows PowerShell. Because I am the only one who writes scripts at my company (in fact, I am the only one who even understands scripting), I write all of my scripts, whether in VBScript or in Windows PowerShell, so that they use command-line arguments. I have a problem, however, when people type in the wrong value for one of my command-line parameters. It can be as simple as they misspell the name of the target computer, but it can be more complicated than that as well. Do you have any special Scripting Guy tricks that you can share with me to help solve this problem?<\/p>\n<\/p>\n<p class=\"MsoNormal\"><br>&#8212; DS<\/p>\n<p class=\"MsoNormal\"><img decoding=\"async\" class=\"nearGraphic\" title=\"Hey, Scripting Guy! Answer\" border=\"0\" alt=\"Hey, Scripting Guy! Answer\" align=\"left\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/a-for-powertip.jpg\" width=\"34\" height=\"34\">Hello DS, <\/p>\n<p class=\"MsoNormal\">I have some great tricks I can share with you. One of my favorite tricks when I am scuba diving is to get down real low (while ensuring that I avoid touching anything) and then when taking pictures I shoot in a more upward direction. This causes the sunlight to reflect through the water, and it brings more blue into the picture. This trick is illustrated in the following picture, which I took while scuba diving off of the coast of <a href=\"http:\/\/en.wikipedia.org\/wiki\/Little_Cayman\"><font face=\"arial,helvetica,sans-serif\">Little Cayman<\/font><\/a>.<\/p>\n<p class=\"Fig-Graphic\"><img decoding=\"async\" title=\"Image of underwater scene near Little Cayman\" alt=\"Image of underwater scene near Little Cayman\" src=\"http:\/\/img.microsoft.com\/library\/media\/1033\/technet\/images\/scriptcenter\/qanda\/hsg\/2009\/july\/hey0715\/hsg-07-15-09-01.jpg\" width=\"600\" height=\"450\"><\/p>\n<p class=\"MsoNormal\"><br>To verify input that is received from the command line, you can use the <b>contains<\/b> operator to examine the contents of an array of possible values. This technique is illustrated here where an array of three values is created and stored in the variable <b>$noun<\/b>. The <b>contains<\/b> operator is then used to see if the array contains &#8220;<a href=\"http:\/\/www.animalinfo.org\/species\/lasikref.htm\"><font face=\"arial,helvetica,sans-serif\">hairy-nosed wombat<\/font><\/a>&#8220;. Because the <b>$noun<\/b> variable does not have an array element that is equal to the string &#8220;hairy-nosed wombat&#8221; the <b>contains<\/b> operator returns <b>False<\/b>. <\/p>\n<p class=\"CodeBlock\"><font size=\"1\"><font face=\"Lucida Sans Typewriter\">PS C:&gt; $noun = &#8220;cat&#8221;,&#8221;dog&#8221;,&#8221;rabbit&#8221;<br>PS C:&gt; $noun -contains &#8220;hairy-nosed wombat&#8221;<br>False<br>PS C:&gt;<\/p>\n<p><\/font><\/font><\/p>\n<p class=\"MsoNormal\">If an array contains a match, the <b>contains<\/b> operator returns <b>True<\/b>. This is seen here: <\/p>\n<p class=\"CodeBlock\"><font size=\"1\"><font face=\"Lucida Sans Typewriter\">PS C:&gt; $noun = &#8220;cat&#8221;,&#8221;dog&#8221;,&#8221;rabbit&#8221;<br>PS C:&gt; $noun -contains &#8220;rabbit&#8221;<br>True<br>PS C:&gt;<\/p>\n<p><\/font><\/font><\/p>\n<p class=\"MsoNormal\">The <b>contains<\/b> operator returns <b>True<\/b> only when there is an exact match. Partial matches return <b>False<\/b>. This is seen here. <\/p>\n<p class=\"CodeBlock\"><font size=\"1\"><font face=\"Lucida Sans Typewriter\">PS C:&gt; $noun = &#8220;cat&#8221;,&#8221;dog&#8221;,&#8221;rabbit&#8221;<br>PS C:&gt; $noun -contains &#8220;bit&#8221;<br>False<br>PS C:&gt;<\/p>\n<p><\/font><\/font><\/p>\n<p class=\"MsoNormal\">The <b>contains<\/b> operator is case insensitive. Therefore, it will return <b>True<\/b> when matched, regardless of case. This is seen here:<\/p>\n<p class=\"CodeBlock\"><font size=\"1\"><font face=\"Lucida Sans Typewriter\">PS C:&gt; $noun = &#8220;cat&#8221;,&#8221;dog&#8221;,&#8221;rabbit&#8221;<br>PS C:&gt; $noun -contains &#8220;Rabbit&#8221;<br>True<br>PS C:&gt;<\/p>\n<p><\/font><\/font><\/p>\n<p class=\"MsoNormal\">If you need to perform a case sensitive match, you can use the case sensitive version of the contains operator&mdash;<b>ccontains<\/b>. As seen here, it will return true only if the case of the string matches the value contained in the array: <\/p>\n<p class=\"CodeBlock\"><font size=\"1\"><font face=\"Lucida Sans Typewriter\">PS C:&gt; $noun = &#8220;cat&#8221;,&#8221;dog&#8221;,&#8221;rabbit&#8221;<br>PS C:&gt; $noun -ccontains &#8220;Rabbit&#8221;<br>False<br>PS C:&gt; $noun -ccontains &#8220;rabbit&#8221;<br>True<br>PS C:&gt;<\/p>\n<p><\/font><\/font><\/p>\n<p class=\"MsoNormal\">In the Get-AllowedComputers.ps1 script, a single command-line parameter is created that is used to hold the name of the target computer for the WMI query. The <b>computer<\/b> parameter is a string, and it receives the default value from the environmental drive. This is a good technique because it ensures the script will have the name of the local computer, which could then be used in producing a report of the results. If you set the value of the computer parameter to <b>localhost<\/b>, you never know what computer the results belong to. This is seen here: <\/p>\n<p class=\"CodeBlock\"><font size=\"1\"><font face=\"Lucida Sans Typewriter\">Param([string]$computer = $env:computername)<\/p>\n<p><\/font><\/font><\/p>\n<p class=\"MsoNormal\">The <b>Get-AllowedComputer<\/b> function is used to create an array of permitted computer names and to check the value of the <b>$computer<\/b> variable to see if it is present. If the value of the <b>$computer<\/b> variable is present in the array, the <b>Get-AllowedComputer<\/b> function returns true. If the value is missing from the array, the <b>Get-AllowedComputer<\/b> function returns false. The array of computer names is created by using the <b>Get-Content<\/b> cmdlet to read a text file that contains a listing of computer names. The text file, Servers.txt, is a plain ASCII text file that has a list of computer names on individual lines:<\/p>\n<p class=\"Fig-Graphic\"><img decoding=\"async\" title=\"Image of the Servers.txt file\" alt=\"Image of the Servers.txt file\" src=\"http:\/\/img.microsoft.com\/library\/media\/1033\/technet\/images\/scriptcenter\/qanda\/hsg\/2009\/july\/hey0715\/hsg-07-15-09-02.jpg\" width=\"241\" height=\"184\"><a href=\"http:\/\/img.microsoft.com\/library\/media\/1033\/technet\/images\/scriptcenter\/qanda\/hsg\/2009\/july\/hey0715\/hsg-07-15-09-02.jpg\"><\/a><\/p>\n<p class=\"MsoNormal\"><br>A text file of computer names is easier to maintain than a hard-coded array that is embedded in the script. In addition, the text file can be placed on a central share and can be used by many different scripts. The <b>Get-AllowedComputer<\/b> function is seen here: <\/p>\n<p class=\"CodeBlock\"><font size=\"1\"><font face=\"Lucida Sans Typewriter\">Function Get-AllowedComputer([string]$computer)<br>{<br><span>&nbsp;<\/span>$servers = Get-Content -path c:fsoservers.txt <br><span>&nbsp;<\/span>$servers -contains $computer<br>} #end Get-AllowedComputer function<\/p>\n<p><\/font><\/font><\/p>\n<p class=\"MsoNormal\">Because the <b>Get-AllowedComputer<\/b> function returns a Boolean value (true or false), it can be used directly in an <b>if<\/b> statement to determine if the value that is supplied for the <b>$computer<\/b> variable is on the permitted list. If the <b>Get-AllowedComputer<\/b> function returns true, the <b>Get-WmiObject<\/b> cmdlet is used to query for BIOS information from the target computer. This is seen here: <\/p>\n<p class=\"CodeBlock\"><font size=\"1\"><font face=\"Lucida Sans Typewriter\">if(Get-AllowedComputer -computer $computer)<br><span>&nbsp;<\/span>{<br><span>&nbsp;&nbsp; <\/span>Get-WmiObject -class Win32_Bios -Computer $computer<br><span>&nbsp;<\/span>}<\/p>\n<p><\/font><\/font><\/p>\n<p class=\"MsoNormal\">On the other hand, if the value of the <b>$computer<\/b> variable is not found in the <b>$servers<\/b> array, a string is displayed that states the computer is not an allowed computer:<\/p>\n<p class=\"CodeBlock\"><font size=\"1\"><font face=\"Lucida Sans Typewriter\">Else<br><span>&nbsp;<\/span>{<br><span>&nbsp; <\/span>&#8220;$computer is not an allowed computer&#8221;<br><span>&nbsp;<\/span>}<\/p>\n<p><\/font><\/font><\/p>\n<p class=\"MsoNormal\">The complete Get-AllowedComputer.ps1 script is seen here. <\/p>\n<p class=\"CodeBlockScreenedHead\"><strong>Get-AllowedComputer.ps1<\/p>\n<p><\/strong><\/p>\n<p class=\"CodeBlockScreened\"><font size=\"1\"><font><font face=\"Lucida Sans Typewriter\">Param([string]$computer = $env:computername)<\/p>\n<p>Function Get-AllowedComputer([string]$computer)<br>{<br><span>&nbsp;<\/span>$servers = Get-Content -path c:fsoservers.txt <br><span>&nbsp;<\/span>$servers -contains $computer<br>} #end Get-AllowedComputer function<\/p>\n<p># *** Entry point to script ***<\/p>\n<p>if(Get-AllowedComputer -computer $computer)<br><span>&nbsp;<\/span>{<br><span>&nbsp;&nbsp; <\/span>Get-WmiObject -class Win32_Bios -Computer $computer<br><span>&nbsp;<\/span>}<br>Else<br><span>&nbsp;<\/span>{<br><span>&nbsp; <\/span>&#8220;$computer is not an allowed computer&#8221;<br><span>&nbsp;<\/span>}<\/p>\n<p><\/font><\/font><\/font><\/p>\n<p class=\"MsoNormal\">You are not limited to only testing for specified computer names in the <b>Get-AllowedComputer<\/b> function. All you need to do is add additional information to the text file. This is seen here:<\/p>\n<p class=\"Fig-Graphic\"><img decoding=\"async\" title=\"Image of ServersAndProperties.txt file\" alt=\"Image of ServersAndProperties.txt file\" src=\"http:\/\/img.microsoft.com\/library\/media\/1033\/technet\/images\/scriptcenter\/qanda\/hsg\/2009\/july\/hey0715\/hsg-07-15-09-03.jpg\" width=\"241\" height=\"225\"><\/p>\n<p class=\"MsoNormal\"><br>A couple of modifications are all that are required to the Get-AllowedComputerAndProperty.ps1 script. The first is to add an additional command-line parameter to allow the user to choose which property to display. This is seen here: <\/p>\n<p class=\"CodeBlock\"><font size=\"1\"><font face=\"Lucida Sans Typewriter\">Param([string]$computer = $env:computername,[string]$property=&#8221;name&#8221;)<\/p>\n<p><\/font><\/font><\/p>\n<p class=\"MsoNormal\">Next, the signature to the <b>Get-AllowedComputer<\/b> function is changed to permit passing of the property name. Instead of directly returning the results of the <b>contains<\/b> operator, the returned values are stored in variables. The <b>Get-AllowedComputer<\/b> function first checks to see if the <b>$servers<\/b> array contains the computer name. It then checks to see if the <b>$servers<\/b> array contains the property name. Each of the resulting values is stored in variables. The two variables are then &ldquo;anded&rdquo; together and the result is returned to the calling code. When two Boolean values are anded together, only the <b>True and True<\/b> case is equal to true. This is seen here: <\/p>\n<p class=\"CodeBlock\"><font size=\"1\"><font face=\"Lucida Sans Typewriter\">PS C:&gt; $true -and $false<\/p>\n<p><\/font><\/font><\/p>\n<p class=\"CodeBlock\"><font size=\"1\"><font face=\"Lucida Sans Typewriter\">False<\/p>\n<p><\/font><\/font><\/p>\n<p class=\"CodeBlock\"><font size=\"1\"><font face=\"Lucida Sans Typewriter\">PS C:&gt; $true -and $true<\/p>\n<p><\/font><\/font><\/p>\n<p class=\"CodeBlock\"><font size=\"1\"><font face=\"Lucida Sans Typewriter\">True<\/p>\n<p><\/font><\/font><\/p>\n<p class=\"CodeBlock\"><font size=\"1\"><font face=\"Lucida Sans Typewriter\">PS C:&gt; $false -and $false<\/p>\n<p><\/font><\/font><\/p>\n<p class=\"CodeBlock\"><font size=\"1\"><font face=\"Lucida Sans Typewriter\">False<\/p>\n<p><\/font><\/font><\/p>\n<p class=\"CodeBlock\"><font size=\"1\"><font face=\"Lucida Sans Typewriter\">PS C:&gt;<\/p>\n<p><\/font><\/font><\/p>\n<p class=\"MsoNormal\">The revised <b>Get-AllowedComputer<\/b> function is seen here: <\/p>\n<p class=\"CodeBlock\"><font size=\"1\"><font face=\"Lucida Sans Typewriter\">Function Get-AllowedComputer([string]$computer, [string]$property)<br>{<br><span>&nbsp;<\/span>$servers = Get-Content -path c:fsoserversAndProperties.txt <br><span>&nbsp;<\/span>$s = $servers -contains $computer<br><span>&nbsp;<\/span>$p = $servers -contains $property<br><span>&nbsp;<\/span>Return $s -and $p<br>} #end Get-AllowedComputer function<\/p>\n<p><\/font><\/font><\/p>\n<p class=\"MsoNormal\">The <b>if<\/b> statement is used to determine if both the <b>computer<\/b> value and the <b>property<\/b> value are contained in the allowed list of servers and properties. If the <b>Get-AllowedComputer<\/b> function returns true, the <b>Get-WmiObject<\/b> cmdlet is used to display the chosen property value from the selected computer. This is seen here: <\/p>\n<p class=\"CodeBlock\"><font size=\"1\"><font face=\"Lucida Sans Typewriter\">if(Get-AllowedComputer -computer $computer -property $property)<br><span>&nbsp;<\/span>{<br><span>&nbsp;&nbsp; <\/span>Get-WmiObject -class Win32_Bios -Computer $computer | <br><span>&nbsp;&nbsp; <\/span>Select-Object -property $property<br><span>&nbsp;<\/span>}<\/p>\n<p><\/font><\/font><\/p>\n<p class=\"MsoNormal\">If the <b>computer<\/b> value and the <b>property<\/b> value are not on the permitted list, the Get-AllowedComputerAndProperty.ps1 script displays a message stating that there is a nonpermitted value. This is seen here: <\/p>\n<p class=\"CodeBlock\"><font size=\"1\"><font face=\"Lucida Sans Typewriter\">Else<br><span>&nbsp;<\/span>{<br><span>&nbsp; <\/span>&#8220;Either $computer is not an allowed computer, `r`nor $property is not an allowed property&#8221;<br><span>&nbsp;<\/span>}<\/p>\n<p><\/font><\/font><\/p>\n<p class=\"MsoNormal\">The complete Get-AllowedComputerAndProperty.ps1 script is seen here. <\/p>\n<p class=\"CodeBlockScreenedHead\"><strong>Get-AllowedComputerAndProperty.ps1<\/p>\n<p><\/strong><\/p>\n<p class=\"CodeBlockScreened\"><font size=\"1\"><font><font face=\"Lucida Sans Typewriter\">Param([string]$computer = $env:computername,[string]$property=&#8221;name&#8221;)<\/p>\n<p>Function Get-AllowedComputer([string]$computer, [string]$property)<br>{<br><span>&nbsp;<\/span>$servers = Get-Content -path c:fsoserversAndProperties.txt <br><span>&nbsp;<\/span>$s = $servers -contains $computer<br><span>&nbsp;<\/span>$p = $servers -contains $property<br><span>&nbsp;<\/span>Return $s -and $p<br>} #end Get-AllowedComputer function<\/p>\n<p># *** Entry point to script ***<\/p>\n<p>if(Get-AllowedComputer -computer $computer -property $property)<br><span>&nbsp;<\/span>{<br><span>&nbsp;&nbsp; <\/span>Get-WmiObject -class Win32_Bios -Computer $computer | <br><span>&nbsp;&nbsp; <\/span>Select-Object -property $property<br><span>&nbsp;<\/span>}<br>Else<br><span>&nbsp;<\/span>{<br><span>&nbsp; <\/span>&#8220;Either $computer is not an allowed computer, `r`nor $property is not an allowed property&#8221;<br><span>&nbsp;<\/span>}<\/p>\n<p><\/font><\/font><\/font><\/p>\n<p class=\"MsoNormal\">DS, we hope you have enjoyed today&#8217;s article, and have found the text file trick at least as interesting as the trick of shooting up toward the surface when you are scuba diving. We have one more article to go in our series about error handling. So join us tomorrow. If you want to be among the first to be informed about everything that is happening on the Script Center, you can <a href=\"https:\/\/twitter.com\/scriptingguys\/\">follow us on Twitter<\/a>. We also make postings at the <a href=\"http:\/\/www.facebook.com\/group.php?gid=5901799452\">Scripting Guys group on Facebook<\/a>. If you get stuck while you are working on a script, you can post to the <a href=\"http:\/\/social.technet.microsoft.com\/Forums\/en\/ITCG\/threads\/\">Official Scripting Guys Forum<\/a>. We have an excellent group of moderators and other active members who are always willing to help other scripters. See you tomorrow. Take care. <\/p>\n<p class=\"MsoNormal\"><b><span>Ed Wilson and Craig Liebendorfer, Scripting Guys<\/span><\/b> <\/p>\n<p class=\"MsoNormal\">&nbsp;<\/p>\n<p class=\"MsoNormal\">&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>&nbsp; I am the script writer at my company, and I have really been enjoying your articles on Windows PowerShell. I have begun the process of converting some of our old VBScripts to Windows PowerShell, and all of my new scripts are written in Windows PowerShell. Because I am the only one who writes scripts [&hellip;]<\/p>\n","protected":false},"author":595,"featured_media":87096,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[22,3,4,45],"class_list":["post-52943","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-retrieving-input","tag-scripting-guy","tag-scripting-techniques","tag-windows-powershell"],"acf":[],"blog_post_summary":"<p>&nbsp; I am the script writer at my company, and I have really been enjoying your articles on Windows PowerShell. I have begun the process of converting some of our old VBScripts to Windows PowerShell, and all of my new scripts are written in Windows PowerShell. Because I am the only one who writes scripts [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/52943","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\/595"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/comments?post=52943"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/52943\/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=52943"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=52943"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=52943"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}