Hey, Scripting Guy! How Can I Use Web Services?

Hey, Scripting Guy! How Can I Use Web Services?

  • Comments 3
  • Likes
Bookmark and Share

 

Hey, Scripting Guy! Question

Hey, Scripting Guy! I remember reading about things called “Web services” a long time ago. It seems that I do not hear much about these anymore. Do they really exist, and if so what are they good for?

-- GK

Hey, Scripting Guy! AnswerHello GK,

Microsoft Scripting Guy Ed Wilson here. We have had to batten down the hatches here in Charlotte, North Carolina, as the tropical storm formerly known as Hurricane Ida makes a guest appearance in our neighborhood. The 50-foot tall southern pines that inhabit my yard are doing their version of the hula, and the handmade specially tuned wind chime on our front porch is playing a ghostly tune. The sky is dark and the wind whips down the street like a freight train crossing the great planes on a mission of sinister importance. Strangely, eerily perhaps, it seems there is no noise—and then it hits—all at once a great cacophony of rushing wind, overturned lawn furniture banging and clanging as it rolls across yards, and all the time the 4/4 staccato of the wind chime marks the beat of an unseen conductor.

GK, because we often receive extreme weather during hurricane season, I am extremely interested in the weather. However, I am even more interested in writing scripts. It would be awesome if I could combine both activities. What one needs is an easy-to-use way to query for current weather information. I know of dozens of Web sites I can go to (including the newly redesigned MSN page) where I can find current weather information. I can, of course, open the Web page in a script and display it, but I prefer a quick and easy way to obtain only the weather information, and to bypass the browser completely. To do this, I need to use a Web service, which returns information in an optimized manner. The data returns in XML format, and an application or script easily parses the information. This requires a little understanding of XML. The complete Get-InternationalWeather.ps1 script shown here illustrates the technique.

Get-InternationalWeather.ps1

#Requires -version 2.0

Function Get-Weather
{
 Param(
  [Parameter(Mandatory=$true)]
  [string]$city,
  [Parameter(Mandatory=$true)]
  [string]$country
 )#end param
 $URI = "http://www.webservicex.net/globalweather.asmx?wsdl"
 $Proxy = New-WebServiceProxy -uri $URI -namespace WebServiceProxy
 $Proxy.GetWeather($city,$country)
} #end Get-Weather

[xml]$xml = Get-Weather -city "sydney airport" -country "Australia"
$xml.CurrentWeather

The Get-InternationalWeather.ps1 script begins by declaring a function named Get-Weather. The Get-Weather function accepts two input parameters, city and country. Both parameters are strings, and both are mandatory. The [Parameter(Mandatory=$true)] tag is new for Windows PowerShell 2.0 and is used to force a parameter to be present when the script runs. If the script runs without values for either the country or the city parameter, the following error appears:

Image of error that appears when script is run without either the country or city parameter

The Get-Weather function parameter section is shown here:

Function Get-Weather
{
 Param(
  [Parameter(Mandatory=$true)]
  [string]$city,
  [Parameter(Mandatory=$true)]
  [string]$country
 )#end param

The Uniform Resource Identifier (URI) string points to the Web Services Description Language (WSDL) page. The WSDL describes the Web service offerings. Each service is a collection of network end points. The WSDL uses XML to define the query method. In the WSDL seen here, the GetWeather method takes two inputs: CityName and CountryName, both of which are strings:

  <?xml version="1.0" encoding="utf-8" ?>
- <wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:tns="http://www.webserviceX.NET" xmlns:s="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" targetNamespace="http://www.webserviceX.NET" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
- <wsdl:types>
- <s:schema elementFormDefault="qualified" targetNamespace="http://www.webserviceX.NET">
- <s:element name="GetWeather">
- <s:complexType>
- <s:sequence>
  <s:element minOccurs="0" maxOccurs="1" name="CityName" type="s:string" />
  <s:element minOccurs="0" maxOccurs="1" name="CountryName" type="s:string" />
  </s:sequence>
  </s:complexType>
  </s:element>

The $URI variable holds the path to the globalweather WSDL. The string assignment listing follows:

$URI = http://www.webservicex.net/globalweather.asmx?wsdl

The key feature of the Get-InternationalWeather.ps1 script uses the New-WebServiceProxy Windows PowerShell cmdlet to make the connection to the globalweather Web service. After the connection to the Web service is established, the resulting connection is stored in the $proxy variable as seen here:

$Proxy = New-WebServiceProxy -uri $URI -namespace WebServiceProxy

It is finally time to retrieve the weather. To do this, call the GetWeather method from the globalweather Web service. The GetWeather method call receives both a city and a country as seen here:

$Proxy.GetWeather($city,$country)
} #end Get-Weather

When calling the GetWeather method, keep in mind that the returned data is XML. The raw XML returned by the GetWeather method is shown here:

<?xml version="1.0" encoding="utf-16"?>
<CurrentWeather>
  <Location>Sydney Airport, Australia (YSSY) 33-57S 151-11E 3M</Location>
  <Time>Nov 12, 2009 - 01:00 PM EST / 2009.11.12 1800 UTC</Time>
  <Wind> from the S (180 degrees) at 22 MPH (19 KT):0</Wind>
  <Visibility> greater than 7 mile(s):0</Visibility>
  <SkyConditions> partly cloudy</SkyConditions>
  <Temperature> 68 F (20 C)</Temperature>
  <DewPoint> 64 F (18 C)</DewPoint>
  <RelativeHumidity> 88%</RelativeHumidity>
  <Pressure> 30.03 in. Hg (1017 hPa)</Pressure>
  <Status>Success</Status>
</CurrentWeather>

[xml]$xml = Get-Weather -city "sydney airport" -country "Australia"

By exploring the contents of the $xml variable, you can see there are two properties that are reported. The first is XML and the second property is CurrentWeather. This is seen here:

PS C:\Users\ed.NWTRADERS> $xml | get-member -MemberType property


   TypeName: System.Xml.XmlDocument

Name           MemberType Definition                                
----           ---------- ----------                                
CurrentWeather Property   System.Xml.XmlElement CurrentWeather {get;}
xml            Property   System.String xml {get;set;}     

The CurrentWeather property returns a CurrentWeather object. This object contains a number of properties that are seen here:

PS C:\Users\ed.NWTRADERS> $xml.CurrentWeather | Get-Member -MemberType property


   TypeName: System.Xml.XmlElement

Name             MemberType Definition                              
----             ---------- ----------                              
DewPoint         Property   System.String DewPoint {get;set;}       
Location         Property   System.String Location {get;set;}        
Pressure         Property   System.String Pressure {get;set;}       
RelativeHumidity Property   System.String RelativeHumidity {get;set;}
SkyConditions    Property   System.String SkyConditions {get;set;}  
Status           Property   System.String Status {get;set;}         
Temperature      Property   System.String Temperature {get;set;}    
Time             Property   System.String Time {get;set;}           
Visibility       Property   System.String Visibility {get;set;}     
Wind             Property   System.String Wind {get;set;}           

Because each of the weather elements is available as an individual property, it is possible to access specific values such as the temperature. This is seen here:

PS C:\Users\ed.NWTRADERS> $xml.CurrentWeather.Temperature
 66 F (19 C)

For the Get-InternationalWeather.ps1 script, the complete weather information is shown. To do this, the CurrentWeather property is queried as seen here:

$xml.CurrentWeather

The result of running the Get-InternationalWeather.ps1 script is shown here:

Image of result of running script

 

Well, GK, as you can see, Web services are alive and well. In fact, they have taken on new importance because of their ease of use from within Windows PowerShell. Join us tomorrow as XML Week continues.

If you want to know exactly what we will be looking at tomorrow, follow us on Twitter or Facebook. If you have any questions, send e-mail to us at scripter@microsoft.com or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.

 

Ed Wilson and Craig Liebendorfer, Scripting Guys

 

Your comment has been posted.   Close
Thank you, your comment requires moderation so it may take a while to appear.   Close
Leave a Comment
  • This method does not work with the default "Hello world" WCF service examples in Visual Studio 2010...

  • Scripting Guy, I have a problem with one particular web service using powershell.  I have scripts that get data from various web services however one in particular wants to return odd UTF-8 characters and I receive the error Exception calling "SMain" with "1" argument(s): "There is an error in XML document (5, -330)."     From my understanding, this works fine when calling from c#.   Is there anything I can do?

  • @Ivan I did not test it with WCF examples.

    @A hmm, not certain.