{"id":16581,"date":"2010-11-07T00:01:00","date_gmt":"2010-11-07T00:01:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2010\/11\/07\/use-powershell-to-retrieve-a-weather-forecast\/"},"modified":"2010-11-07T00:01:00","modified_gmt":"2010-11-07T00:01:00","slug":"use-powershell-to-retrieve-a-weather-forecast","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/use-powershell-to-retrieve-a-weather-forecast\/","title":{"rendered":"Use PowerShell to Retrieve a Weather Forecast"},"content":{"rendered":"<p>&nbsp;<\/p>\n<p><b>Summary:<\/b> Microsoft Scripting Guy Ed Wilson shows how to use Windows PowerShell to get a weather forecast from inside the Windows PowerShell ISE.<\/p>\n<p>&nbsp;<\/p>\n<p>Microsoft Scripting Guy Ed Wilson here. It is amazing how quickly things change on the Internet. A couple of years ago I found a website that hosted several web services. It was really cool. Most of the services were easy to use and were well documented. Unfortunately, that site is rarely up any longer. In fact, it seems to be down more frequently than it is up. I began looking around for a more reliable web service to retrieve weather information, and I came across <a href=\"http:\/\/www.weather.gov\/xml\/#use_it\">the United States National Weather Service&#8217;s website<\/a>. I figured they would be more reliable than the other web service I was using. This gave me an opportunity to re-write my old weather script, to return a Windows PowerShell object by using the Windows PowerShell V2 style of object creation (supply the properties in a hash table). <\/p>\n<p>I ended up writing two versions of my script. The first is a traditional script, and the second is a script file that contains only the function itself. If I configure the function as a Windows PowerShell script, I have to add command line parameters to allow for flexibility. The <b>Get-UsGovWeather.ps1<\/b> script is seen here.<\/p>\n<p style=\"padding-left: 30px\"><strong>Get-UsGovWeather.ps1<\/strong><\/p>\n<p style=\"padding-left: 60px\"><span style=\"font-family: courier new,courier\">Param (<\/span><\/p>\n<p style=\"padding-left: 60px\"><span style=\"font-family: courier new,courier\">&nbsp;$zip = 28201,<\/span><\/p>\n<p style=\"padding-left: 60px\"><span style=\"font-family: courier new,courier\">&nbsp;$numberDays = 3<\/span><\/p>\n<p style=\"padding-left: 60px\"><span style=\"font-family: courier new,courier\">)<\/span><\/p>\n<p style=\"padding-left: 60px\"><span style=\"font-family: courier new,courier\">Function Get-UsGovWeather<\/span><\/p>\n<p style=\"padding-left: 60px\"><span style=\"font-family: courier new,courier\">{<\/span><\/p>\n<p style=\"padding-left: 60px\"><span style=\"font-family: courier new,courier\">&nbsp;Param([string]$zip,<\/span><\/p>\n<p style=\"padding-left: 60px\"><span style=\"font-family: courier new,courier\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [int]$numberDays<\/span><\/p>\n<p style=\"padding-left: 60px\"><span style=\"font-family: courier new,courier\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; )<\/span><\/p>\n<p style=\"padding-left: 60px\"><span style=\"font-family: courier new,courier\">$URI = &#8220;http:\/\/www.weather.gov\/forecasts\/xml\/DWMLgen\/wsdl\/ndfdXML.wsdl&#8221;<\/span><\/p>\n<p style=\"padding-left: 60px\"><span style=\"font-family: courier new,courier\">$Proxy = New-WebServiceProxy -uri $URI -namespace WebServiceProxy<\/span><\/p>\n<p style=\"padding-left: 60px\"><span style=\"font-family: courier new,courier\">[xml]$latlon=$proxy.LatLonListZipCode($zip)<\/span><\/p>\n<p style=\"padding-left: 60px\"><span style=\"font-family: courier new,courier\">foreach($l in $latlon)<\/span><\/p>\n<p style=\"padding-left: 60px\"><span style=\"font-family: courier new,courier\">{<\/span><\/p>\n<p style=\"padding-left: 60px\"><span style=\"font-family: courier new,courier\">&nbsp;$a = $l.dwml.latlonlist -split &#8220;,&#8221;<\/span><\/p>\n<p style=\"padding-left: 60px\"><span style=\"font-family: courier new,courier\">&nbsp;$lat = $a[0]<\/span><\/p>\n<p style=\"padding-left: 60px\"><span style=\"font-family: courier new,courier\">&nbsp;$lon = $a[1]<\/span><\/p>\n<p style=\"padding-left: 60px\"><span style=\"font-family: courier new,courier\">&nbsp;$sDate = get-date -UFormat %Y-%m-%d<\/span><\/p>\n<p style=\"padding-left: 60px\"><span style=\"font-family: courier new,courier\">&nbsp;$format = &#8220;Item24hourly&#8221;<\/span><\/p>\n<p style=\"padding-left: 60px\"><span style=\"font-family: courier new,courier\">&nbsp;[xml]$weather = $Proxy.NDFDgenByDay($lat,$lon,$sDate,$numberDays,$format)<\/span><\/p>\n<p style=\"padding-left: 60px\"><span style=\"font-family: courier new,courier\">&nbsp;For($i = 0 ; $i -le $numberDays -1 ; $i ++)<\/span><\/p>\n<p style=\"padding-left: 60px\"><span style=\"font-family: courier new,courier\">&nbsp;{<\/span><\/p>\n<p style=\"padding-left: 60px\"><span style=\"font-family: courier new,courier\">&nbsp; New-Object psObject -Property @{<\/span><\/p>\n<p style=\"padding-left: 60px\"><span style=\"font-family: courier new,courier\">&nbsp; &#8220;Date&#8221; = ((Get-Date).addDays($i)).tostring(&#8220;MM\/dd\/yyyy&#8221;) ;<\/span><\/p>\n<p style=\"padding-left: 60px\"><span style=\"font-family: courier new,courier\">&nbsp; &#8220;maxTemp&#8221; = $weather.dwml.data.parameters.temperature[0].value[$i] ;<\/span><\/p>\n<p style=\"padding-left: 60px\"><span style=\"font-family: courier new,courier\">&nbsp; &#8220;minTemp&#8221; = $weather.dwml.data.parameters.temperature[1].value[$i] ;<\/span><\/p>\n<p style=\"padding-left: 60px\"><span style=\"font-family: courier new,courier\">&nbsp; &#8220;Summary&#8221; = $weather.dwml.data.parameters.weather.&#8221;weather-conditions&#8221;[$i].&#8221;Weather-summary&#8221;}<\/span><\/p>\n<p style=\"padding-left: 60px\"><span style=\"font-family: courier new,courier\">&nbsp;} <\/span><\/p>\n<p style=\"padding-left: 60px\"><span style=\"font-family: courier new,courier\">}<\/span><\/p>\n<p style=\"padding-left: 60px\"><span style=\"font-family: courier new,courier\">} #end function Get-UsGovWeather<\/span><\/p>\n<p style=\"padding-left: 60px\"><span style=\"font-family: courier new,courier\">&nbsp;<\/span><\/p>\n<p style=\"padding-left: 60px\"><span style=\"font-family: courier new,courier\"># ***** Entry point to script ***<\/span><\/p>\n<p style=\"padding-left: 60px\"><span style=\"font-family: courier new,courier\">&nbsp;<\/span><\/p>\n<p style=\"padding-left: 60px\"><span style=\"font-family: courier new,courier\">Get-UsGovWeather -zip $zip -numberDays $numberDays | <\/span><\/p>\n<p style=\"padding-left: 60px\"><span style=\"font-family: courier new,courier\">Format-Table -Property date, maxTemp, minTemp, Summary -AutoSize<\/span><\/p>\n<p>&nbsp;<\/p>\n<p>Because I use default values for the command line parameters, the script can be run by dragging it to the Windows PowerShell console and pressing <b>Enter<\/b>. Of course, if you want to compare the weather from your home with that of another location, use the up arrow, and add the <i>-zip<\/i> parameter. To view the weather for more than the default three days, use the <i>-numberdays<\/i> parameter. The commands and the associated outputs are seen in the following figure.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/2465.WES-11-07-10-01.jpg\" border=\"0\" \/><\/p>\n<p>&nbsp;<\/p>\n<p>Most of the time I will be using the <b>Get-UsGovWeather <\/b>function inside my Windows PowerShell ISE. Because the function returns an object, the output can be easily sorted and arranged by using Windows PowerShell cmdlets. The problem is that is too much work when all one wants to do is to get a quick weather forecast. The solution is twofold. First, I store the function in a .ps1 script file that is kept in my ISEProfileModule folder. The function is only the function code, without any default values and without any formatting. A good function returns a rich object that can be processed later as required. The behavior is like a Windows PowerShell cmdlet. The <b>Get-UsGovWeather<\/b> function is seen here.<\/p>\n<p style=\"padding-left: 30px\"><strong>Get-UsGovWeather<\/strong><\/p>\n<p style=\"padding-left: 30px\"><span style=\"font-family: courier new,courier\">Function Get-UsGovWeather<\/span><\/p>\n<p style=\"padding-left: 30px\"><span style=\"font-family: courier new,courier\">{<\/span><\/p>\n<p style=\"padding-left: 30px\"><span style=\"font-family: courier new,courier\">&nbsp;Param([string]$zip,<\/span><\/p>\n<p style=\"padding-left: 30px\"><span style=\"font-family: courier new,courier\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [int]$numberDays<\/span><\/p>\n<p style=\"padding-left: 30px\"><span style=\"font-family: courier new,courier\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; )<\/span><\/p>\n<p style=\"padding-left: 30px\"><span style=\"font-family: courier new,courier\">$URI = &#8220;http:\/\/www.weather.gov\/forecasts\/xml\/DWMLgen\/wsdl\/ndfdXML.wsdl&#8221;<\/span><\/p>\n<p style=\"padding-left: 30px\"><span style=\"font-family: courier new,courier\">$Proxy = New-WebServiceProxy -uri $URI -namespace WebServiceProxy<\/span><\/p>\n<p style=\"padding-left: 30px\"><span style=\"font-family: courier new,courier\">[xml]$latlon=$proxy.LatLonListZipCode($zip)<\/span><\/p>\n<p style=\"padding-left: 30px\"><span style=\"font-family: courier new,courier\">foreach($l in $latlon)<\/span><\/p>\n<p style=\"padding-left: 30px\"><span style=\"font-family: courier new,courier\">{<\/span><\/p>\n<p style=\"padding-left: 30px\"><span style=\"font-family: courier new,courier\">&nbsp;$a = $l.dwml.latlonlist -split &#8220;,&#8221;<\/span><\/p>\n<p style=\"padding-left: 30px\"><span style=\"font-family: courier new,courier\">&nbsp;$lat = $a[0]<\/span><\/p>\n<p style=\"padding-left: 30px\"><span style=\"font-family: courier new,courier\">&nbsp;$lon = $a[1]<\/span><\/p>\n<p style=\"padding-left: 30px\"><span style=\"font-family: courier new,courier\">&nbsp;$sDate = get-date -UFormat %Y-%m-%d<\/span><\/p>\n<p style=\"padding-left: 30px\"><span style=\"font-family: courier new,courier\">&nbsp;$format = &#8220;Item24hourly&#8221;<\/span><\/p>\n<p style=\"padding-left: 30px\"><span style=\"font-family: courier new,courier\">&nbsp;[xml]$weather = $Proxy.NDFDgenByDay($lat,$lon,$sDate,$numberDays,$format)<\/span><\/p>\n<p style=\"padding-left: 30px\"><span style=\"font-family: courier new,courier\">&nbsp;For($i = 0 ; $i -le $numberDays -1 ; $i ++)<\/span><\/p>\n<p style=\"padding-left: 30px\"><span style=\"font-family: courier new,courier\">&nbsp;{<\/span><\/p>\n<p style=\"padding-left: 30px\"><span style=\"font-family: courier new,courier\">&nbsp; New-Object psObject -Property @{<\/span><\/p>\n<p style=\"padding-left: 30px\"><span style=\"font-family: courier new,courier\">&nbsp; &#8220;Date&#8221; = ((Get-Date).addDays($i)).tostring(&#8220;MM\/dd\/yyyy&#8221;) ;<\/span><\/p>\n<p style=\"padding-left: 30px\"><span style=\"font-family: courier new,courier\">&nbsp; &#8220;maxTemp&#8221; = $weather.dwml.data.parameters.temperature[0].value[$i] ;<\/span><\/p>\n<p style=\"padding-left: 30px\"><span style=\"font-family: courier new,courier\">&nbsp; &#8220;minTemp&#8221; = $weather.dwml.data.parameters.temperature[1].value[$i] ;<\/span><\/p>\n<p style=\"padding-left: 30px\"><span style=\"font-family: courier new,courier\">&nbsp; &#8220;Summary&#8221; = $weather.dwml.data.parameters.weather.&#8221;weather-conditions&#8221;[$i].&#8221;Weather-summary&#8221;}<\/span><\/p>\n<p style=\"padding-left: 30px\"><span style=\"font-family: courier new,courier\">&nbsp;} <\/span><\/p>\n<p style=\"padding-left: 30px\"><span style=\"font-family: courier new,courier\">}<\/span><\/p>\n<p style=\"padding-left: 30px\"><span style=\"font-family: courier new,courier\">} #end function Get-UsGovWeather<\/span><\/p>\n<p>&nbsp;<\/p>\n<p>This folder is seen in the following figure.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/1727.WES-11-07-10-02.jpg\" border=\"0\" \/><\/p>\n<p>&nbsp;<\/p>\n<p>After the function is stored in my profile module location, I then create a short function in my Windows PowerShell ISE profile to display only the weather configuration I want. The function that I put in my Windows PowerShell ISE profile is seen here.<\/p>\n<p style=\"padding-left: 30px\"><span style=\"font-family: courier new,courier\">Function Get-MyWeather<br \/>{<br \/>. $moduleHome\\iseProfileModule\\Get-UsGovWeatherFunction.ps1<br \/>Get-UsGovWeather -zip 29745 -numberDays 3 | <br \/>Format-Table -Property date, maxTemp, minTemp, Summary -AutoSize<br \/>}<\/span><\/p>\n<p>&nbsp;<\/p>\n<p>The Windows PowerShell ISE profile is seen in the following figure.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/0513.WES-11-07-10-03.jpg\" border=\"0\" \/><\/p>\n<p>&nbsp;<\/p>\n<p>The cool thing is that the weather is now immediately available. I type <b>get-MyWeather<\/b> (actually I type get-my and press &lt;tab&gt; to retrieve the current weather. The output is shown in the following figure.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/3771.WES-11-07-10-04.jpg\" border=\"0\" \/><\/p>\n<p>&nbsp;<\/p>\n<p>Well, that is about it for messing around with web services, and the Windows PowerShell ISE profile. Join me tomorrow as I begin talking about object member discovery. It should be a very good week. <\/p>\n<p>&nbsp;<\/p>\n<p>I invite you to follow me on <a target=\"_blank\" href=\"http:\/\/bit.ly\/scriptingguystwitter\">Twitter<\/a> or <a href=\"http:\/\/bit.ly\/scriptingguysfacebook\">Facebook<\/a>. If you have any questions, send email to me at <a target=\"_blank\" href=\"mailto:scripter@microsoft.com\">scripter@microsoft.com<\/a> or post them on the <a target=\"_blank\" href=\"http:\/\/bit.ly\/scriptingforum\">Official Scripting Guys Forum<\/a>. See you tomorrow. Until then, peace.<\/p>\n<p>&nbsp;<\/p>\n<p><b>Ed Wilson, Microsoft Scripting Guy<\/b><\/p>\n","protected":false},"excerpt":{"rendered":"<p>&nbsp; Summary: Microsoft Scripting Guy Ed Wilson shows how to use Windows PowerShell to get a weather forecast from inside the Windows PowerShell ISE. &nbsp; Microsoft Scripting Guy Ed Wilson here. It is amazing how quickly things change on the Internet. A couple of years ago I found a website that hosted several web services. [&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":[25,51,2,3,61,45],"class_list":["post-16581","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-displaying-output","tag-getting-started","tag-running","tag-scripting-guy","tag-weekend-scripter","tag-windows-powershell"],"acf":[],"blog_post_summary":"<p>&nbsp; Summary: Microsoft Scripting Guy Ed Wilson shows how to use Windows PowerShell to get a weather forecast from inside the Windows PowerShell ISE. &nbsp; Microsoft Scripting Guy Ed Wilson here. It is amazing how quickly things change on the Internet. A couple of years ago I found a website that hosted several web services. [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/16581","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=16581"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/16581\/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=16581"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=16581"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=16581"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}