Using the GET Method with PowerShell and RESTful APIs

In my last post focused on dealing with RESTful APIs via PowerShell, I went fairly deep into how to construct the required key-value pair for Basic Authentication. This is a common and simple process for providing credentials needed to authenticate against an endpoint / resource over HTTPS. The next step is to create an API request. To start, I wanted to go through the process using the GET method, which retrieves data and should always be idempotent.

While the goal is to showcase how to construct a GET request, a realistic endpoint makes it simpler. I’ll do this using a Rubrik cluster as my API endpoint. However, the principles shouldn’t deviate significantly across other systems.

Let’s start by ripping apart the “good bits” from my Get-RubrikSLA cmdlet from GitHub. This cmdlet uses the GET method to request data from the Rubrik cluster with details on all of the available Service Level Agreement (SLA) Domains. These are policy abstractions that are logically coupled with workloads to express the desired protection values. If I remove all of the fancy function wrappings off the cmdlet, we’re left with this bare-bones set of code:

# Build the URI (Universal Resource Identifier), also known as the Resource or Endpoint
$server = 'brik1.rubrik.demo'
$uri = 'https://'+$server+':443/slaDomain'

# Submit the request to the RESTful Resource using the GET method
try 
{
    $r = Invoke-WebRequest -Uri $uri -Headers $global:RubrikHead -Method Get
    $result = ConvertFrom-Json -InputObject $r.Content
}
catch 
{
    throw $_
}

I’m going to break this apart into smaller chunks and explain what’s going on with the script.

Taking Apart the Script

The first few lines are there to set up the variables used later in the script. I try to avoid hard coding variables into the script body, preferring instead to either declare them at the top or (better yet) allow the user to input them by defining parameters. But, this is just a simple script for demonstration purposes, so I’ve hard coded them at the top.

The $server variable contains the FQDN of my Rubrik cluster. The $uri variable builds the Universal Resource Identifier (URI) which is the endpoint / resource that I’m going to send my GET request to.

# Build the URI (Universal Resource Identifier), also known as the Resource or Endpoint
$server = 'brik1.rubrik.demo'
$uri = 'https://'+$server+':443/slaDomain'

Now that the variables are out of the way, I wrap the Invoke-WebRequest cmdlet within a Try / Catch. If you’re new to this, go read my Using Try and Catch with PowerShell’s Invoke-WebRequest post. The response is saved to a throw-away variable (meaning I often re-use it later) named $r. If the API request results in an error, the Try will fail and the code within the Catch area will execute.

$r = Invoke-WebRequest -Uri $uri -Headers $global:RubrikHead -Method Get

Assuming the request did not suffer an error, $r variable will hold a wealth of response data from the API endpoint. Here’s an example:

api-request-get-response

Yikes! In its raw form, the response isn’t all that helpful. Much of the information is inconsequential to the script. The most common keys that I find myself using are:

  • StatusCode
  • StatusDescription
  • Content

While the StatusCode and StatusDescription aren’t used in this example script, they are handy for validating that the API request was successful. This is especially true for requests that are doing something – such as a PUT or POST that updates data. For a GET request, I find that it’s often enough to check the Content key to see if any data was returned. If not, we can assume that either no data exists or the request was not submitted correctly in some fashion.

Formatting the Content Key

Most RESTful APIs use JSON or XML to transmit data back and forth. PowerShell can natively convert this sort of data into something it can use and is easier on the eyeballs. This is where the last important bit of code comes into play.

By passing the value of $r.Content into the ConvertFrom-Json cmdlet, we can format the body of the response into something useful. That data is held within the $result variable. It is this variable that drives all future possibilities from the script.

$result = ConvertFrom-Json -InputObject $r.Content

Let’s see how the value of Content looks after getting a JSON massage from PowerShell:

result-json-powershell

That’s a much more familiar looking hash table (key-value pairs). Using the ISESteroids variable explorer can also show the data in a GUI-friendly manner.

isesteroids-var-explorer

Using the Data

Here’s an example of what you can do with the resulting data from a GET request. Perhaps you’re curious how many virtual machines are being protected by each SLA Domain? Easy enough.

Just pass the $results variable over to a Select-Object cmdlet and pick which properties are relevant. I’ve chosen name and numVms and have asked PowerShell to format the results into a table with the -AutoSize parameter to force the columns to snuggle up to one another. 🙂

$result | Select-Object -Property name,numVms | Format-Table -AutoSize
vms-in-sla-domains-powershell

There’s a near-infinite number of things you can do with the data, and I often find myself using the GET method to provide user details or drive further automation that issues a PUT, POST, or PATCH. In my next post on this topic, I’ll use data from this request to update a virtual machine’s SLA Domain using the PATCH method.