Working with Web Services, SOAP, PHP and all the REST with PowerShell

By and large, most of the services APIs and tools you’ll find on the web which are meant to be interactive will be either SOAP, RESTful or a PHP/Forms based service.

The goal of this post is to give you an example of how to use each of these standards to interact with the various systems you may run across.

Not only for the web

You may have noticed on the past few posts here that I’m really getting into APIs. “What’s so great about APIs?” you may ask.

APIs allow you to very easily leverage work that someone else has done to quickly create your own functions and get seriously useful stuff out of just a little bit of work. If you’re planning to Orchestrate workflows in your environment, or create runbooks for your data center too, or if you want to make your own tools, learning how to interact with SOAP, REST and WebServices will definitely be in your favor.

The real reason you want to do this is so that you can make your own tools, and not be dependent on someone else creating a module or PowerShell functions for you. Pretty much all of the high-end datacenter tools like RiverBed WAN Optimizers, NetApp storage controllers or StorageVaults had published REST APIs, or supported SOAP (which can be accessed via a WebService Proxy) long before they ever made PowerShell cmdlets.

If you want to be on the bleeding edge of orchestrating and automating your environment, it pays to know this stuff.

Deciding which tool to use for which service

The key distinguishing factor for our service will be found in the URL of the resource… If our URL looks like X, then it is a Y service, and you use Z tool to get to it

URL

Service Type

Cmdlet

Ends in .asmx or ?WSDL

SOAP

New-WebServiceProxy

Contains API, especially api/v2

REST

Invoke-RESTMethod

Ends in .php

PHP/Form

Invoke-WebRequest

REST v. Soap, whats the difference?

This is a great question that came up during our user’s group last night. Both REST and SOAP are simply methods of accessing information presented via web services. It will suffice to say that REST is now in vogue, and is generally believed to be easier to use and manage than SOAP, which tends to be a bit heavier on XML.

The best answer I’ve seen came from Dr. M. Ekelstein, who put it the following way:
“A nice analogy for REST vs. SOAP is mailing a letter: with SOAP, you’re using an envelope; with REST, it’s a postcard. ”

In his blog he gives an example, comparing the response you can expect from SOAP vs. the response from REST. In both examples, we’re querying for the results of a user ‘12345’. Note the tremendous verbosity of one reply over the other.

 

SOAP REST
<?xml version=”1.0″?><soap:Envelope
xmlns:soap=”http://www.w3.org/2001/12/soap-envelope&#8221;
soap:encodingStyle=”http://www.w3.org/2001/12/soap-encoding”&gt;
<soap:body pb=”http://www.acme.com/phonebook”&gt;
<pb:GetUserDetails>
<pb:UserID>12345</pb:UserID>
</pb:GetUserDetails>
</soap:Body>
</soap:Envelope>
http://www.acme.com/phonebook/UserDetails/12345

You can imagine how much work would go into parsing out the real juicy bits from the result on the left, versus the result on the right.

Simply put, if you have the option, use REST, it’s much easier to deal with the return objects!

Working with SOAP Protocol

So, you’ll know if your service if SOAPy if it says so, or if the access URL of your device ends in .asmx?WSDL, which is short for Web Services Description Language.

The overall flow of accessing resources from a SOAP source are to access the source using New-WebServiceProxy, storing the results in a variable. You’ll then run Get-Member to look at the methods your WebService offers, and then go from there with accessing it.

You can generally view a WSDL in your browser by launching it. It will be human readable (should!) XML code. Fortunately, rather than scrolling through pages and pages of XML, PowerShell can enumerate it for you using the New-WebServiceProxy cmdlet.

For example:

$url = "http://www.webservicex.net/length.asmx?WSDL"
$proxy = New-WebServiceProxy $url
$proxy | gm -memberType Method
TypeName: .AutogeneratedTypes.WebServiceProxy 
 
Name            MemberType Definition
----            --------- ----------
ChangeLengthUnitCompleted Event 
BeginChangeLengthUnit Method System.IAsyncResult 
ChangeLengthUnit      Method double ChangeLengthUnit
ChangeLengthUnitAsync Method void ChangeLengthUnitAsync
EndChangeLengthUnit   Method double EndChangeLengthUnit
ToString Method string ToString()

So, this helpful output lets us see which Methods this particular SOAP WebService allows us. Let’s take a peek at the .ChangeLengthUnit() method.

methods

Those definition types are super long! It basically abbreviates down to (“NumberOfUnits”,”StartingLengthUnit”,”EndingLengthUnit”)

We can give it a try with the following.

$serviceProxy.ChangeLengthUnit(15,"Meters","Inches")
   
>590.551181102362

Pretty nifty!

Working with REST

REST APIs are written by the developers of a device, application or hardware, when they have extensibility in mind. REST Urls will almost always contain the words ‘api’ somewhere within their URL.

For this example, we’ll refer back to my Get-Weather function I released about a month ago. When I originally wrote that, I was using Invoke-WebRequest (Which is effectively just loading the web page and scraping it’s contents! I’ve since had a come to Jesus meeting and fixed my code there )

Here are the most pertinent bits of that function:

$API_key = "$secret"
$url = "https://api.forecast.io/forecast/$API_key/$coords"
#Store the results in $weather
$weather = Invoke-RestMethod $url -Method Get

#Display the contents of $weather
$weather
   
latitude :      33.9533
longitude :  -84.5406
timezone :    America/New_York
offset :          -5
currently :  @{time=1416415006; summary=Clear; icon=clear-day; nearestStormDistance=235; nearestStormBearing=321; precipIntensity=0;
precipProbability=0; temperature=38.67; apparentTemperature=36.25; dewPoint=20.8; humidity=0.48; windSpeed=3.54; windBearing=249;
visibility=10; cloudCover=0.09; pressure=1029.21; ozone=321.84}
minutely :     @{summary=Clear for the hour.; icon=clear-day; data=System.Object[]}
hourly :         @{summary=Partly cloudy starting this afternoon, continuing until this evening.; icon=partly-cloudy-day; data=System.Object[]}
daily :            @{summary=Light rain on Saturday through Tuesday, with temperatures rising to 67░F on Monday.; icon=rain; data=System.Object[]}
flags :           @{sources=System.Object[]; isd-stations=System.Object[]; darksky-stations=System.Object[]; madis-stations=System.Object[];
lamp-stations=System.Object[]; units=us}

So,now that we’ve seen how easy it is to work with these object oriented services, let’s take a deeper peak under the covers with some PHP/Forms manipulation using PowerShell’s built-in FaceBook example.

Working with PHP/Web Forms Objects

Now, that we’ve seen how comparatively easy these were, let’s see how we’d attack a .php/forms login.

One of the things to note about using Invoke-WebRequest is that you’ll be getting cozy with the HTTP Verbs of Get, Post, Delete, and others. For this example, we’ll use Get and Post.

We’ll run our test using the easiest .php that I know of, the Form Post Tester service on Hashemian.com’s blog.
The usage of this service is that you can post any data you’d like to the php system, in the -Body param of your submission. You can pull the data back down later if you append a ‘/’ and a key to your submission, which is handy for testing your HTTP Get.

Here’s an example.

$FormtesterUrl  = http://www.hashemian.com/tools/form-post-tester.php
$accessCode = "/FoxDeploy"
$URI = $FormtesterUrl + $accesscode
Invoke-WebRequest -Uri $uri -Method Post -Body "Test Message From PowerShell"

If you want to test that it worked, you can open up the full URL in a browser, and see something like this.

PostTestweb

Now to pull the data back down from there, we’ll do an use the ‘Get’ method instead.

Invoke-WebRequest -Uri http://www.hashemian.com/tools/form-post-tester.php/FoxDeploy -Method Get | Select -expand Content

PostTestPosh

In more complex scenarios, you could read the HTML of a page and provide values for all of the fields on a page to log in. If you check the Get-Help example, you’ll find a very ambitious example that allows you to log into Facebook with PowerShell!

Advertisements

6 thoughts on “Working with Web Services, SOAP, PHP and all the REST with PowerShell

  1. edifice kw May 12, 2015 / 8:10 pm

    hello!,I like your writing so much! share we keep in touch
    extra approximately your post on AOL? I need an expert on this area to resolve
    my problem. May be that is you! Looking ahead to look you.

    • FoxDeploy May 12, 2015 / 8:37 pm

      Wow, a poster from the past! I’m surprised anyone still uses AOL.

  2. Chris June 24, 2016 / 10:48 am

    Hey! This is a really good article – thanks for writing it! I was hoping the article would go into the next step of things (i.e. how do you tell PowerShell to return back specific properties of an object). Any chance you’ve got some cool examples of that?

    • FoxDeploy June 24, 2016 / 11:52 am

      No but I’ve been looking for my next blog post topic!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s