Getting Ready for Orchestrator 2012: Accessing REST Web Services using PowerShell

As I’m playing around with our pre-beta build of Orchestrator, I’m building lots of little tools for interacting with it in a number of ways. I had been doing some PowerShell to interact with the COM interfaces so I could import and export runbooks, but I also needed an easy way to access things like the start parameters of a runbook so I could invoke it with the right parameters. Since Orchestrator 2012 has a new REST-based web service with lots of functionality, I naturally thought of how I could use that. I didn’t want to build a full-fledged app, so I wondered if I could interact with it using PowerShell scripts. The answer is – of course!

A quick Bing search led me to this blog post, https://spowser.wordpress.com/2009/03/13/powershell-rest-client/ , where the author creates a simple REST client using a script. I Adapted that code a little and produced a quick script that would let me send URL strings and get back an XML object, a raw XML string, or a JSON-formatted string. It was surprisingly easy. The hard part is making sure you have the URL query string correct. I’ll build out more stuff on that later, but for now I just wanted to share the simple REST client.

Here’s the code. There are three functions; “Request-REST” which does the request and gets back the data, “Create-Credentials” which simplifies creating a NetworkCredential object for use by Request-Rest, and a Fix-URI function to ensure the URI string is formatted correctly with a trailing slash.

 
function Request-Rest{
    
    [CmdletBinding()]
  PARAM (
        [Parameter(Mandatory=$true)]
        [String] $URL,
        
        [Parameter(Mandatory=$true)]
        [System.Net.NetworkCredential] $credentials,
                
        [Parameter(Mandatory=$false)]
        [String] $UserAgent = "PowerShell API Client",
        
        [Parameter(Mandatory=$false)]
        [Switch] $JSON,
        
        [Parameter(Mandatory=$false)]
        [Switch] $Raw
    
    
  )
    #Create a URI instance since the HttpWebRequest.Create Method will escape the URL by default.   
    $URL = Fix-Url $Url
    $URI = New-Object System.Uri($URL,$true)   
    #Create a request object using the URI   
    $request = [System.Net.HttpWebRequest]::Create($URI)   
    #Build up a nice User Agent   
    $request.UserAgent = $(   
        "{0} (PowerShell {1}; .NET CLR {2}; {3})" -f $UserAgent, $(if($Host.Version){$Host.Version}else{"1.0"}),  
        [Environment]::Version,  
        [Environment]::OSVersion.ToString().Replace("Microsoft Windows ", "Win")  
        )
    $request.Credentials = $credentials
    
    if ($PSBoundParameters.ContainsKey('JSON'))
    {
        $request.Accept = "application/json"
    }
            
    try
    {
        [System.Net.HttpWebResponse] $response = [System.Net.HttpWebResponse] $request.GetResponse()
    }
    catch
    {
         Throw "Exception occurred in $($MyInvocation.MyCommand): `n$($_.Exception.Message)"
    }
    
    $reader = [IO.StreamReader] $response.GetResponseStream()  
    if (($PSBoundParameters.ContainsKey('JSON')) -or ($PSBoundParameters.ContainsKey('Raw')))
    {
        $output = $reader.ReadToEnd()  
    }
    else
    {
        [xml]$output = $reader.ReadToEnd()  
    }
    
    $reader.Close()  
    Write-Output $output  
    $response.Close()
}
function Create-Credentials{
    [CmdletBinding()]
  PARAM (
        [Parameter(Mandatory=$true)]
        [String] $domain,
        
        [Parameter(Mandatory=$true)]
        [String] $username,
                
        [Parameter(Mandatory=$true)]
        [String] $password 
    
  )
    $creds = New-Object System.Net.NetworkCredential($username,$password,$domain)  
    return $creds
}
Function Fix-Url ($url) {
    if($url.EndsWith('/') -Or $url.EndsWith('\')) {
        return $url
    }
    
    "$url/"
}

Now just create a credentials object like this:

$creds = Create-Credentials "DOMAIN" "USERNAME" "PASSWORD"

and then use the credentials in the command. Here are examples of the three formats:

Request-Rest -URL "https://SCOSERVER:81/Orchestrator.svc/Folders/" -credentials $creds

Request-Rest -URL "https://SCOSERVER:81/Orchestrator.svc/Folders/" -credentials $creds –Raw

Request-Rest -URL "https://SCOSERVER:81/Orchestrator.svc/Folders/" -credentials $creds –JSON

Depending on the switch you used you will either get an XML object, a raw XML string, or JSON-formatted string.

Enjoy!