{"id":808,"date":"2014-08-18T00:01:00","date_gmt":"2014-08-18T00:01:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2014\/08\/18\/powershell-mini-scripting-games-2014-answer-1\/"},"modified":"2014-08-18T00:01:00","modified_gmt":"2014-08-18T00:01:00","slug":"powershell-mini-scripting-games-2014-answer-1","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/powershell-mini-scripting-games-2014-answer-1\/","title":{"rendered":"PowerShell Mini-Scripting Games 2014: Answer 1"},"content":{"rendered":"<p><b style=\"font-size:12px\">Summary<\/b><span style=\"font-size:12px\">: Here is the answer to Problem 1 in Windows PowerShell Mini-Scripting Games 2014.<\/span>\nMicrosoft Scripting Guy, Ed Wilson, is here. Here is an answer to Problem 1 in Windows PowerShell Mini-Scripting Games 2014. Last week, I posted <a href=\"http:\/\/blogs.technet.com\/b\/heyscriptingguy\/archive\/2014\/08\/11\/powershell-mini-scripting-games-2014-event-1.aspx\" target=\"_blank\">the complete Problem 1 description and task outline<\/a>.<\/p>\n<h2>Problem one synopsis<\/h2>\n<p>You are reading a CSV file that was created from another source. The CSV file has four fields that are to be read and then used to update four attributes in Active Directory. The problem is that the CSV file does not have all four fields filled out. In some cases, there is a space in the field, in others a tab, others are null, and others are empty.\nWhen a field does not have a proper value, the attempt to update the attribute in Active Directory results in an error message. Your boss has decided to make the script your problem.<\/p>\n<h2>Solution<\/h2>\n<p>You need to write some logic that will identify all sorts of white space, including null fields. Detecting a null, a space, or a whatever seems to beg for a nice regular expression. It is also possible to do this manually by using a series of <b>if<\/b> statements.<\/p>\n<p style=\"margin-left:30px\"><b>Note&nbsp;<\/b> For a great reference, see <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/az24scfc(v=vs.110).aspx\" target=\"_blank\">Regular Expression Language &#8211; Quick Reference<\/a>.\nFor example, if I want to match a space, I can simply supply a space, as shown here:<\/p>\n<p style=\"margin-left:30px\">PS C:&gt; $a = &#8221; &#8220;<\/p>\n<p style=\"margin-left:30px\">PS C:&gt; $a -match &#8221; &#8220;<\/p>\n<p style=\"margin-left:30px\">True\nIs <b>$a<\/b> null? I can also test that:<\/p>\n<p style=\"margin-left:30px\">PS C:&gt; $a = $null<\/p>\n<p style=\"margin-left:30px\">PS C:&gt; $a -match $null<\/p>\n<p style=\"margin-left:30px\">True\nI can incorporate this into logic, and use code that looks like the following:<\/p>\n<p style=\"margin-left:30px\">PS C:&gt; If ($a -match &#8221; &#8221; -OR $a -match $null) {&#8216;$a is either a space or null&#8217;}<\/p>\n<p style=\"margin-left:30px\">$a is either a space or null<\/p>\n<h3>Match a whitespace character<\/h3>\n<p>I can use a character class to try to match the empty field. Whitespace characters are things like a space, a tab, a carriage return, or a line feed. The regular expression character class for whitespace characters is backslash with a lowercase s: ( <b>s<\/b> ). Windows PowerShell uses a backtick with a lowercase t for a Tab: ( <b>`t<\/b> ).<\/p>\n<p style=\"margin-left:30px\"><b>Note&nbsp;<\/b> Regular expression character classes are case sensitive. There is an excellent description of character classes on MSDN: <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/20bw873z(v=vs.110).aspx\" target=\"_blank\">Character Classes in Regular Expressions<\/a>. &nbsp;\n<span style=\"font-size:12px\">In my first example, I use the Windows PowerShell <\/span><b style=\"font-size:12px\">`t<\/b><span style=\"font-size:12px\"> character to store a Tab character in the variable <\/span><b style=\"font-size:12px\">$a<\/b><span style=\"font-size:12px\">. I then display it to the console, which is really nothing to see.<\/span><\/p>\n<p style=\"margin-left:30px\">PS C:&gt; $a = &#8220;`t&#8221;<\/p>\n<p style=\"margin-left:30px\">PS C:&gt; $a\nNow, I attempt to match a space, which does not match a Tab. This is shown here:<\/p>\n<p style=\"margin-left:30px\">PS C:&gt; $a -match &#8221; &#8220;<\/p>\n<p style=\"margin-left:30px\">False\nNow I use the <b>s<\/b> whitespace character class from Regular Expressions, and I can see that it does match:<\/p>\n<p style=\"margin-left:30px\">PS C:&gt; $a -match &#8220;s&#8221;<\/p>\n<p style=\"margin-left:30px\">True\nOf course, it will also match the Windows PowerShell Tab character, <b>`t<\/b>:<\/p>\n<p style=\"margin-left:30px\">PS C:&gt; $a -match &#8220;`t&#8221;<\/p>\n<p style=\"margin-left:30px\">True\nBut the whitespace class does not match a null, as shown here:<\/p>\n<p style=\"margin-left:30px\">PS C:&gt; $a = $null<\/p>\n<p style=\"margin-left:30px\">PS C:&gt; $a -match &#8220;s&#8221;<\/p>\n<p style=\"margin-left:30px\">False\nBut it will match one or more spaces. This is shown here:<\/p>\n<p style=\"margin-left:30px\">PS C:&gt; $a = &#8221; &#8220;<\/p>\n<p style=\"margin-left:30px\">PS C:&gt; $a -match &#8220;s&#8221;<\/p>\n<p style=\"margin-left:30px\">True<\/p>\n<p style=\"margin-left:30px\">PS C:&gt; $a = &#8221;&nbsp; &#8220;<\/p>\n<p style=\"margin-left:30px\">PS C:&gt; $a -match &#8220;s&#8221;<\/p>\n<p style=\"margin-left:30px\">True<\/p>\n<h3>How about not matching<\/h3>\n<p>Rather than trying to match every possible blank or empty sort of thing, how about if I simply don&rsquo;t match any letter or number? I can easily do this by specifying a couple of character groups. All lower case letters, all upper case letters, and all numbers will pretty much do it. To specify a character group, I use square brackets for all lower case letters <b>[a-z]<\/b> or for all upper case letters <b>[A-Z]<\/b>. The asterisk ( <b>*<\/b> ) means zero or more instances of the characters.\nI create my two character groups and store them in a variable I call <b>pattern<\/b>:<\/p>\n<p style=\"margin-left:30px\">$pattern = &#8220;[a-z][A-Z]*&#8221;\nNow I check to see if it does not match my various test conditions. First I check to see if It does not match a blank space:<\/p>\n<p style=\"margin-left:30px\">PS C:&gt; $pattern = &#8220;[a-z][A-Z]*&#8221;<\/p>\n<p style=\"margin-left:30px\">PS C:&gt; $a = &#8221; &#8220;<\/p>\n<p style=\"margin-left:30px\">PS C:&gt; $a -notmatch $pattern<\/p>\n<p style=\"margin-left:30px\">True\nThen I check to see if it does not match a null:<\/p>\n<p style=\"margin-left:30px\">PS C:&gt; $a = $null<\/p>\n<p style=\"margin-left:30px\">PS C:&gt; $a -notmatch $pattern<\/p>\n<p style=\"margin-left:30px\">True\nNow I check to see if it does not match a Tab and a carriage return line feed:<\/p>\n<p style=\"margin-left:30px\">PS C:&gt; $a = &#8220;`t&#8221;<\/p>\n<p style=\"margin-left:30px\">PS C:&gt; $a -notmatch $pattern<\/p>\n<p style=\"margin-left:30px\">True<\/p>\n<p style=\"margin-left:30px\">PS C:&gt; $a = &#8220;`r`n&#8221;<\/p>\n<p style=\"margin-left:30px\">PS C:&gt; $a -notmatch $pattern<\/p>\n<p style=\"margin-left:30px\">True<\/p>\n<h3>Application to the problem<\/h3>\n<p>So, if I create a simple CSV file that has a few empty fields, it might look like the following:<\/p>\n<p style=\"margin-left:30px\">&#8220;f1&#8243;,&#8221;f2&#8243;,&#8221;f3&#8243;,&#8221;f4&#8221;<\/p>\n<p style=\"margin-left:30px\">&#8220;a&#8221;,&#8221;b&#8221;,&#8221;c&#8221;,&#8221;d&#8221;<\/p>\n<p style=\"margin-left:30px\">&#8220;&#8221;,&#8221;b&#8221;,&#8221;c&#8221;,&#8221;d&#8221;<\/p>\n<p style=\"margin-left:30px\">&#8220;a&#8221;,&#8221; &#8220;,&#8221;c&#8221;,&#8221;d&#8221;\nNow, I write a script that reads this CSV file, and contains the pattern I used earlier. To walk through the CSV file, I use the <b>GetEnumerator() <\/b>method. I then use <b>While<\/b> and the <b>MoveNext()<\/b> method to proceed from each record to the next one. I then use an <b>IF<\/b> statement to see if I find a match. Here is the script:<\/p>\n<p style=\"margin-left:30px\">PROBLEM1SOLUTION.PS1<\/p>\n<p style=\"margin-left:30px\">$data = Import-Csv -Path C:DataInq1.csv<\/p>\n<p style=\"margin-left:30px\">$pattern = &#8220;[a-z][A-Z]*&#8221;<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp; $e = $data.GetEnumerator()<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp; While ($e.MoveNext())<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; If ($e.current.f1 -notmatch $pattern) {&#8220;$($e.current)&nbsp; does not match&#8221;}<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; If ($e.current.f2 -notmatch $pattern) {&#8220;$($e.current)&nbsp; does not match&#8221;}<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; If ($e.current.f3 -notmatch $pattern) {&#8220;$($e.current)&nbsp; does not match&#8221;}<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; If ($e.current.f4 -notmatch $pattern) {&#8220;$($e.current)&nbsp; does not match&#8221;}<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;\nThat is one approach to the problem. Mini-Scripting Games Answer Week will continue tomorrow when I will have a solution for Problem 2.\nI invite you to follow me on <a href=\"http:\/\/bit.ly\/scriptingguystwitter\" target=\"_blank\">Twitter<\/a> and <a href=\"http:\/\/bit.ly\/scriptingguysfacebook\" target=\"_blank\">Facebook<\/a>. If you have any questions, send email to me at <a href=\"http:\/\/blogs.technet.commailto: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.\n<b>Ed Wilson, Microsoft Scripting Guy<\/b><span style=\"font-size:12px\">&nbsp;<\/span><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Summary: Here is the answer to Problem 1 in Windows PowerShell Mini-Scripting Games 2014. Microsoft Scripting Guy, Ed Wilson, is here. Here is an answer to Problem 1 in Windows PowerShell Mini-Scripting Games 2014. Last week, I posted the complete Problem 1 description and task outline. Problem one synopsis You are reading a CSV file [&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":[191,169,521,526,3,4,45],"class_list":["post-808","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-community","tag-csv-and-other-delimited-files","tag-mini-scripting-games","tag-regex","tag-scripting-guy","tag-scripting-techniques","tag-windows-powershell"],"acf":[],"blog_post_summary":"<p>Summary: Here is the answer to Problem 1 in Windows PowerShell Mini-Scripting Games 2014. Microsoft Scripting Guy, Ed Wilson, is here. Here is an answer to Problem 1 in Windows PowerShell Mini-Scripting Games 2014. Last week, I posted the complete Problem 1 description and task outline. Problem one synopsis You are reading a CSV file [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/808","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=808"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/808\/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=808"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=808"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=808"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}