A PowerShell Weather Service

I’ve been having some fun this week sharing a few tools for getting weather information and forecasts using PowerShell. To complete the story, today I have one more technique. Using PowerShell, you can query a web service for weather information. In simple terms a web service is like an application you can “run” via a web connection and sometimes even in a browser. The web service has “methods” you can invoke to do something. In the past if you wanted to interact with a web service in PowerShell you most likely needed to get down and dirty with the .NET Framework. Then PowerShell 3.0 brought us a new cmdlet, New-WebServiceProxy. With this cmdlet you can create an object that in essence becomes a wrapper to the web service. The web service methods become the object’s methods. Let me show you.

First, I’ll create my proxy object.

This object also has methods:

So how do I use the GetWeather method?

Seems straight forward. Let’s try. Wonder what it is like someplace warm?

Interesting. I can read it, but this sure looks like XML. If so, I should be able to retrieve the weather as an XML document.

Now I can explore it.

Wow. This seems simple. All I need is the CurrentWeather property and I have an easy to read result. I could probably run this as a one-liner.

Not necessarily easy to read but it works.

What about another city? Perhaps Charlotte, North Carolina, the site of the upcoming PowerShell Summit.

Well that worked, but that isn’t the city I had in mind. Going back to the web service methods, I remember seeing something to get cities by country. Let’s try that.

More XML. That’s find. I can use Select-XML to parse out the City node.

Now, expand each node.

Let’s try with the US now and find cities with Charlotte in the name.

It seems to me that the weather service data comes primarily from locations with airports. So if you live in a town without an airport, the best you can probably do is find a location near you with an airport. But now that I see what I need for Charlotte, North Carolina, I can revise my command.

Much better. But I don’t want to have to do that much typing for all of this so I put together a few functions to simplify the entire process. First, is a function to get a location.

The function does all the work of creating the web service proxy and retrieving cities by country. You can change the default to your country. I also added a parameter that will match on a city name.

I then wrote a function to make it easier to get weather information.

In looking at the XML, there were a few minor issues. One, the Wind node was repeated so I decided to combine the two into a single property. I also noticed that some of the node values had extra spaces. So I trimmed up the values as a I built an ordered hashtable which I then turned into a custom object. The end result is an easy to use tool.

You can even pipe between commands.

The object properties are all strings which means sorting or filtering is troublesome, but there is some good data here so I guess it is a trade-off.

Now you have several ways to check the weather, assuming you can’t simply look out a window. And hopefully you’ve learned a few new things about PowerShell along the way.

Find and Replace Text with PowerShell

magnifying-glass I’ve just finished up a series of tweets with a follower who had a question about finding and replacing a bit of data in a text file. In his case it was a web.config file but it really could be any text file that you can view in PowerShell. In PowerShell 3.0 and later this isn’t too difficult. Although I haven’t tested with really large files to determine if there are any limitations. Before you try anything I’m going to show you, please have a backup copy of of the original file.

Let’s say I have a file like this:

I need to change the IP source address in the connection string. As you probably guessed Get-Content is going to come into play. Normally when you use Get-Content you get an array of strings which adds a little complexity. But starting in v3 Get-Content has a -Raw parameter which writes the entire file as a single string. If we have a single string then we can easily use -Replace.

Your replacement pattern could even be a regular expression pattern. This could even be done as a one-liner:

For many of you, especially with unstructured text files, this technique should get the job done. But in this case, because the text file is also an XML document we could tackle the problem a different way. This is especially useful if you have several changes you want to make to the file.

First, create an XML document from the file.

We can navigate the document until we find the entry we need to change.

xmlconfig

We can assign a new value with revised connection string:

All that remains is to save the file back to disk.

Or, if you didn’t necessarily know the structure of your document, you could use an XPath query with Select-XML to find the node and then change the value.

The node properties will vary depending on your XML file so you will need to look at the object.
xmlnode

The XML approach is a bit more involved but is predictable and you don’t have to save the file until you have the XML just the way you want it.

One thing I will say about both techniques is that the more you understand how to use regular expressions in PowerShell the more you can accomplish. If you are feeling a little wobbly on the topic, there is an entire chapter on regular expressions in PowerShell in Depth.