{"id":55183,"date":"2008-08-12T02:08:00","date_gmt":"2008-08-12T02:08:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2008\/08\/12\/hey-scripting-guy-when-will-we-land\/"},"modified":"2008-08-12T02:08:00","modified_gmt":"2008-08-12T02:08:00","slug":"hey-scripting-guy-when-will-we-land","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/hey-scripting-guy-when-will-we-land\/","title":{"rendered":"Hey, Scripting Guy! When Will We Land?"},"content":{"rendered":"<p><span class=\"Apple-style-span\"><\/p>\n<h2><font class=\"Apple-style-span\" face=\"Verdana\" size=\"3\"><span class=\"Apple-style-span\"><font class=\"Apple-style-span\" face=\"Arial\" size=\"6\"><span class=\"Apple-style-span\"><\/span><\/font><\/span><\/font><\/h2>\n<p><img decoding=\"async\" class=\"nearGraphic\" title=\"Hey, Scripting Guy! Question\" height=\"34\" alt=\"Hey, Scripting Guy! Question\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/q-for-powertip.jpg\" width=\"34\" align=\"left\" border=\"0\" \/> <\/p>\n<p>Hey, Scripting Guy! I am writing to you offline because I am stuck in an airplane somewhere over the Atlantic Ocean. It seems like I have been flying for two weeks, and I am really getting tired of looking at the bald spot on the head in front of me. Do you know when we will land?<\/p>\n<p>&#8212; DS<\/p>\n<p><img decoding=\"async\" height=\"5\" alt=\"Spacer\" src=\"https:\/\/devblogs.microsoft.com\/scripting\/wp-content\/uploads\/sites\/29\/2019\/05\/spacer.gif\" width=\"5\" border=\"0\" \/><img decoding=\"async\" class=\"nearGraphic\" title=\"Hey, Scripting Guy! Answer\" height=\"34\" alt=\"Hey, Scripting Guy! Answer\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/a-for-powertip.jpg\" width=\"34\" align=\"left\" border=\"0\" \/><a href=\"http:\/\/go.microsoft.com\/fwlink\/?linkid=68779&amp;clcid=0x409\"><\/a> <\/p>\n<p>Hi DS,<\/p>\n<p>I am not sure the pilots themselves really know when you will land. The funny thing is that late plane arrival excuses sound an awful lot like the excuses I used to give to my users when I was a network administrator:<\/p>\n<p>User: My computer is slow.<\/p>\n<p>SG: Must be network congestion.<\/p>\n<p>Passenger: Why are we going to be late?<\/p>\n<p>Pilot: Must be airport congestion.<\/p>\n<p>You get the idea. Anyway, even though we could write your &#8220;When Will We Land?&#8221; script in VBScript (using<b>DateDiff<\/b>&nbsp;and&nbsp;<b>CDate<\/b>), we have been playing around with Windows PowerShell quite a bit lately, and we came across a cmdlet called&nbsp;<b>Write-Progress<\/b>&nbsp;that might just be cool enough to incorporate into your script. Here is what such a script might look&nbsp;like:<\/p>\n<pre class=\"codeSample\">$arriveTime = get-date -hour 16 -minute 42\n$now = get-date\n$arrival = ($arriveTime - $now).totalMinutes\n$activity = \"Arrival Time\" \n\nFor($i = 0 ; $i -le [int]$arrival ; $i ++)\n      {\n        write-progress  -activity \"$($arrival-$i) minutes till $activity\" `\n                        -percentComplete  ($i\/[int]$arrival*100) `\n                        -status \"watched minute $i ...\"\n       start-sleep -seconds 60\n    } # end for\n<\/pre>\n<p>Our script begins by creating a&nbsp;<b>DateTime<\/b>&nbsp;object that is equal to our estimated arrival time. This command is very similar to using the<b>CDate<\/b>&nbsp;function from VBScript. By using the&nbsp;<b>-hour<\/b>&nbsp;parameter and the&nbsp;<b>-minute<\/b>&nbsp;parameters of the&nbsp;<b>Get-Date<\/b>&nbsp;cmdlet, we create a<b>DateTime<\/b>&nbsp;object that represents an arbitrary point in time in the future (and in the case of airplanes, a fictional time object as well). We can see this line of code here:<\/p>\n<pre class=\"codeSample\">$arriveTime = get-date -hour 16 -minute 45<\/pre>\n<p>Next, we once again use the&nbsp;<b>Get-Date<\/b>&nbsp;cmdlet, only this time we do not use any parameters. When we do this, we are emulating the functionality of the&nbsp;<b>Date<\/b>&nbsp;function from VBScript. It simply returns the current system time as a&nbsp;<b>DateTime<\/b>&nbsp;object. We store this object in a variable we called&nbsp;<b>$now<\/b>. This line of code is seen here:<\/p>\n<pre class=\"codeSample\">$now = get-date<\/pre>\n<p>Note: Remember that all variables in Windows PowerShell begin with a dollar sign, which means that in Europe and in other places in the world they are really inexpensive to use these days. I&#8217;ll be here all week; try the veal.<\/p>\n<p>Now we create another variable called&nbsp;<b>$arrival<\/b>. Instead of having to use the&nbsp;<b>DateDiff<\/b>&nbsp;function to subtract two different time objects, we simply subtract the two time objects. Because we are interested only in the total number of minutes, we put parentheses around the two time objects and tell it to give us the&nbsp;<b>totalMinutes<\/b>&nbsp;property. This is seen here:<\/p>\n<pre class=\"codeSample\">$arrival = ($arriveTime - $now).totalMinutes<\/pre>\n<p>This next line of code is simple; we just need to store a string into a variable. The string could say anything, but because we are interested in when we will arrive, we thought it best to at least reflect that sentiment as seen here:<\/p>\n<pre class=\"codeSample\">$activity = \"Arrival Time\"<\/pre>\n<p>It is now time for a good old-fashioned&nbsp;<b>For\/Next<\/b>&nbsp;loop. However, in Windows PowerShell there is no&nbsp;<b>Next<\/b>&nbsp;in the&nbsp;<b>For\/Next<\/b>&nbsp;loop. In VBScript, of course, there was a&nbsp;<b>Next<\/b>&nbsp;in the loop, which is why I call it a&nbsp;<b>For\/Next<\/b>&nbsp;loop. I guess in reality, it is simply a&nbsp;<b>For<\/b>&nbsp;loop.<\/p>\n<p>In Windows PowerShell the For loop has both smooth parentheses and curly brackets (or braces or crinkly things). The For loop begins with a parenthesis. Inside the parentheses are three sections. The first section tells the loop where to begin. The next section tells the loop how far to go, and the last section tells the loop how to get there. In our&nbsp;<b>For<\/b>&nbsp;loop (seen here without the script block code), we begin at 0 and go until we are less than or equal to the number of minutes stored in the&nbsp;<b>$arrival<\/b>&nbsp;variable. Lastly, we will get to that number by incrementing the value of the&nbsp;<b>$i<\/b>&nbsp;variable by&nbsp;one.<\/p>\n<pre class=\"codeSample\">For($i = 0 ; $i -le [int]$arrival ; $i ++)\n{\n} # end for\n<\/pre>\n<p>Now we come to the&nbsp;<b>Write-Progress<\/b>&nbsp;cmdlet. There are a few parameters we are going to use:&nbsp;<b>activity<\/b>,&nbsp;<b>percentComplete<\/b>, and<b>status<\/b>. These parameter names are rather self explanatory.&nbsp;<b>Activity<\/b>&nbsp;tells you what the progress indicator is measuring. In our case, we subtract the value of&nbsp;<b>$i<\/b>&nbsp;from the number of minutes we stored when we computed how long we had until we arrived, and then we print out the string value we stored in the&nbsp;<b>$activity<\/b>&nbsp;variable. The dollar sign outside the parentheses indicates we want to perform a subexpression (and I used to think a subexpression was something like \u201cdown periscope.\u201d) The subexpression is required here to force the expression inside the parentheses to be evaluated first. Otherwise we would get a rather strange looking activity report. This part of the&nbsp;<b>Write-Progress<\/b>&nbsp;command is seen here:<\/p>\n<pre class=\"codeSample\">write-progress  -activity \"$($arrival-$i) minutes till $activity\"<\/pre>\n<p>Next, we want to figure out the percentage of completion of the activity we are timing. In other words, we want to know the percent of elapsed time for our trip. So, to do this, we are back in high school math class to figure out percentages. We take the&nbsp;<b>$i<\/b>&nbsp;variable that is used to count up to the number of minutes, the&nbsp;<b>$arrival<\/b>&nbsp;variable that stores the total number of minutes, multiply by 100, and divide the two numbers, and we arrive at a percent of elapsed time (don\u2019t ask me, but it does seem to work right; I actually tested it on a recent flight from Lisbon). This part of the code is seen here:<\/p>\n<pre class=\"codeSample\">-percentComplete  ($i\/[int]$arrival*100)<\/pre>\n<p>Now, for la piece de resistance (or not): the status parameter will tell you how long the script has been marking time. Cool, huh? This line is seen here (the ellipsis is optional):<\/p>\n<pre class=\"codeSample\">-status \"watched minute $i ...\"<\/pre>\n<p>To introduce an element of accuracy to the script, as we are counting minutes we need to ensure the loop takes about a minute, so we use the&nbsp;<b>Start-Sleep<\/b>&nbsp;cmdlet (which is PowerShell for&nbsp;<b>wscript.sleep<\/b>). The good thing about the&nbsp;<b>Start-Sleep<\/b>&nbsp;cmdlet is we have both the<b>-seconds<\/b>&nbsp;parameter and the&nbsp;<b>-milliseconds<\/b>&nbsp;parameter. We can therefore avoid the higher math requirements of multiplying everything by 1,000 to get seconds. Sweet! Here is that line of code:<\/p>\n<pre class=\"codeSample\">start-sleep -seconds 60<\/pre>\n<p>The completed&nbsp;<b>For<\/b>&nbsp;loop is seen&nbsp;here.<\/p>\n<pre class=\"codeSample\">For($i = 0 ; $i -le [int]$arrival ; $i ++)\n      {\n        write-progress  -activity \"$($arrival-$i) minutes till $activity\" `\n                                      -percentComplete  ($i\/[int]$arrival*100) `\n                                      -status \"watched minute $i ...\"\n       start-sleep -seconds 60\n    } # end for\n<\/pre>\n<p>When the script is run, after you configure the appropriate time values in 24-hour time format, on the first line of code the script will print out a status bar such as this one:<\/p>\n<p><img decoding=\"async\" height=\"255\" alt=\"Status bar graphic\" src=\"http:\/\/img.microsoft.com\/library\/media\/1033\/technet\/images\/scriptcenter\/qanda\/whenwillweland_75x75.jpg\" width=\"508\" border=\"0\" \/> <\/p>\n<p><font class=\"Apple-style-span\" face=\"Verdana\" size=\"3\"><span class=\"Apple-style-span\"><b><b><\/b><\/b><\/span><\/font>&nbsp;<\/p>\n<p><font class=\"Apple-style-span\" face=\"Verdana\" size=\"3\"><span class=\"Apple-style-span\"><b><b>Ed Wilson and Craig Liebendorfer, Scripting Guys<\/b><br \/><\/b><\/span><\/font><\/p>\n<p><font class=\"Apple-style-span\" face=\"Verdana\" size=\"3\"><b><\/b><\/font><\/span><font class=\"Apple-style-span\" face=\"Verdana\" size=\"3\"><\/font><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hey, Scripting Guy! I am writing to you offline because I am stuck in an airplane somewhere over the Atlantic Ocean. It seems like I have been flying for two weeks, and I am really getting tired of looking at the bald spot on the head in front of me. Do you know when we [&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":[13,3,4,45],"class_list":["post-55183","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-dates-and-times","tag-scripting-guy","tag-scripting-techniques","tag-windows-powershell"],"acf":[],"blog_post_summary":"<p>Hey, Scripting Guy! I am writing to you offline because I am stuck in an airplane somewhere over the Atlantic Ocean. It seems like I have been flying for two weeks, and I am really getting tired of looking at the bald spot on the head in front of me. Do you know when we [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/55183","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=55183"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/55183\/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=55183"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=55183"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=55183"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}