Understanding the Invoke-RestMethod PowerShell cmdlet

Reading and manipulating information via API is commonplace for developers and DevOps these days, and PowerShell has a built-in command specifically built for working with representational state transfer (REST) APIs called Invoke-RestMethod.

REST APIs allow developers to interact with various services over HTTP/HTTPS and follow a common methodology of using methods to read and manipulate information. They return information in a standard way, typically through JavaScript Object Notation (JSON). The Invoke-RestMethod cmdlet is built with REST in mind. It allows the user to invoke various methods for web service APIs and easily parse the output.

To explain the Invoke-RestMethod command, let's start with a simple example. Let's say I'm fiending for some information about cats and discover a REST API called Cat Facts. This API returns various facts about our feline friends and is a great API to demonstrate how Invoke-RestMethod works.

All REST APIs have a base URL and one or more endpoints. The base URL for Cat Facts is https://cat-fact.herokuapp.com, and the endpoint we'll be using is /facts. When we combine these, we get the endpoint URI or https://cat-fact.herokuapp.com/facts.

One of the Invoke-RestMethod command's biggest advantages is its native parsing ability. Invoke-RestMethod understands that a URI is REST and will probably return JSON. When the API does return JSON, Invoke-RestMethod will parse the JSON and return useful PowerShell objects. To demonstrate, I'll use the Invoke-RestMethod command's brother, Invoke-WebRequest. The Invoke-WebRequest command performs a similar function by sending HTTP verbs to web services but does not have the parsing ability Invoke-RestMethod does.

If I run Invoke-WebRequest against our Cat Facts API, we have to look at the Content property, which contains a whole lot of unparsed JSON.

Using Invoke WebRequest against a REST API

Using Invoke WebRequest against a REST API

We could parse this JSON ourselves, but there's no need when using Invoke-RestMethod. This command looks at the output and parses it. Here's the difference:

Using Invoke RestMethod

Using Invoke RestMethod

Notice we didn't have to specify the Content property at all. Invoke-RestMethod natively returns the HTTP content and automatically parses the JSON, allowing us to work with the JSON data via PowerShell objects.

Invoke-RestMethod also has some other useful features when working with REST APIs, such as authentication. Some APIs require you to authenticate via a username/password with basic authentication or perhaps an OAuth token. We can use the Credential parameter to pass a username and password if the API supports basic authentication. Usually, though, you'll find a lot of APIs require an OAuth token. For a great explanation on working with OAuth with PowerShell, check out Stephen Owen's blog post.

The Invoke-RestMethod command allows you to pass OAuth tokens and other information the API needs via HTTP headers using the Headers parameter. Perhaps the REST API is set up to accept OAuth tokens using the command Authorization key. We can pass our OAuth token with Invoke-RestMethod like so:

This command doesn't just retrieve information via APIs using the HTTP GET method sent by default. We can use many different HTTP methods like POST, PATCH, PUT, and UPDATE as well. We simply need to specify the method via the Method parameter and then provide an HTTP body using the Body parameter.

Perhaps we have a REST API that accepts a POST request and expects the body to be in JSON format. We've already saved our JSON payload in a variable called $jsonSample looking something like this:

We can pass this JSON payload to the Body parameter and optionally use the ContentType parameter to tell the API that the payload is JSON. This step isn't always required, but it is common. Our Invoke-RestMethod API call would then look something like this:

P

The command above will authenticate to the URI endpoint, pass the JSON sample via the HTTP POST method, and tell the API that the content is JSON. If the API returns a response, Invoke-RestMethod will return it to the console already parsed.

The Invoke-RestMethod command is a great way to interact with REST APIs in PowerShell. Although most if not all of its functionality can take place via a combination of Invoke-WebRequest, ConvertTo-Json, and ConvertFrom-Json commands, it's a great all-in-one command that does all the heavy lifting for you.

Want to write for 4sysops? We are looking for new authors.

Read 4sysops without ads and for free by becoming a member!

4+
avataravatar
Share
6 Comments
  1. I would add something:

    • some Body needs to be converted to JSON with `| ConvertTo-Json`
    • I would splat both   $body and $header
    • No matter if the output is JSON or XML we can nicely format it through `Format-List` without need to install any Format Gallery and it will be more readable in the terminal

    ```

    $body = @{
    "UserSessionId"="12345678"
    "OptionalEmail"="lanakane@test.com"
    } | ConvertTo-Json

    $header = @{
    "Accept"="application/json"
    "connectapitoken"="29a696c910b441989e367afa23c3c31c"
    }

    $params = @{
    Uri = 'http://NZL075/WSVistaWebClient/RESTLoyalty.svc/member/search'
    Headers = $header
    Method = 'POST'
    Body = $body
    ContentType = 'application/json'
    }

    Invoke-RestMethod @params | Format-List

    ```

    2+

  2. Busla 1 year ago

    Invoke-RestMethod has bad design. It totally useless to interact with REST APIs. There are not unified way to get result code. Invoke-RestMethod throw exception on 404 and similar answers.

    1+

  3. Angela 1 year ago

    example does not work Cannot bind parameter 'Uri'. Cannot convert the "System.Collections.Hashtable" value of type "System.Collections.Hashtable" to type "System.Uri".

    1+

  4. Betelgeuse 5 months ago

    Hi,

    I am a newby with PS.

    I am tryng to adapt linux commands to PS1 ones (normally creating also a PS1 script).

    Option #1

    C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -file D:\scripts\ps1\script001.ps1 "User" "Password" https://..URL.../WebApi ComputerClone -WSOPparam_body {"p1"="a" "p2"="b" "p3"="c" "p4"="d"}

    Option #2

    C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -file D:\scripts\ps1\script.ps1 "User" "Password" https://...URL.../WebApi ComputerClone -WSOPparam1 a -WSOPparam2 b -WSOPparam3 c -WSOPparam4 d

    The script doe or should do:

    [...]

         #$WSOPparam_body | ConvertTo-Json  ???

         or

         #$body = $WSOPparam_body ???

         $header = @{
            "Accept"           = "application/json"
            "connectapitoken"  = "97fe6ab5b1a640909551e36a071ce9ed"
            "Content-Type"     = "application/json"
     

     Invoke-RestMethod -Method $method -uri $WS_URI_out -cred $cred -Body $body -Headers $header

    How to make this work?

    Thanks in advance.

    0

  5. John Saad 2 months ago

    $token = curl -X POST https://api.lulu.com/auth/realms/glasstree/protocol/openid-connect/token -d 'grant_type=client_credentials' -H 'Content-Type: application/x-www-form-urlencoded' -H 'Authorization: Basic xxx'

    $obj = $token | convertfrom-json | select-object access_token
    $access_token = $obj.access_token

    $url = 'https://api.sandbox.lulu.com/print-jobs/'
    $headers = @{ 'Authorization' = 'Bearer $access_token' }

    Invoke-RestMethod -method 'post' -uri $url -headers $headers -contenttype 'application/json'

     

     

    This returns Invoke-RestMethod: {"detail":"Error decoding signature"}

    Do you know what that means?

    0

Leave a reply

Your email address will not be published. Required fields are marked *

*

© 4sysops 2006 - 2020

CONTACT US

Please ask IT administration questions in the forums. Any other messages are welcome.

Sending

Log in with your credentials

or    

Forgot your details?

Create Account