Working with REST API in PowerShell using Invoke-RestMethod

The RESTful API is a widely used method for online data transmission, offering a secure, fast, and easiest way to retrieve data from a server and post data to a server. In this post, we will explore how to make REST API calls from PowerShell, covering CRUD operations through different HTTP methods like GET, POST, PATCH, PUT, and DELETE.

PowerShell supports the Invoke-RestMethod cmdlet, which helps us to send HTTP and HTTPS requests to REST web services and get response as structured data based on the return data type. For instance, when a REST API delivers a response in JSON or XML format, PowerShell automatically converts (or deserializes) the response content into [PSCustomObject] objects.

GET Request – Retrieve Data Using the GET Method

The GET HTTP method is utilized for fetching data from a server and is often referred to as a read API because it only requests data without modifying the server’s state. The command below demonstrates how to request data from a sample API and display the response content in the PowerShell console.

$Response = Invoke-RestMethod -Uri "https://reqres.in/api/users"
$Response | FL

The above command returns the users as a collection of objects in the property “data”. The following command retrieves the data and exports the users list to a CSV file.

$Response = Invoke-RestMethod -Uri "https://reqres.in/api/users"
$Response.data | Export-CSV "C:\Temp\Sample-Users.CSV" -NoTypeInformation -Encoding UTF8 

GET Method – Use OAuth Access Token in Request Headers

The previous approach sends an HTTP GET request to an open web service without including the authentication token or key. However, in real-time applications, every API should be protected, requiring us to send the necessary authentication details or credentials through request headers.

In the following example, we utilize the Microsoft Graph API endpoint to retrieve Office 365 users by including the required OAuth Access token in the request headers.

$APIUri = "https://graph.microsoft.com/v1.0/users"
$AccessToken = "eyJ0eXAiOi...." #Replace your OAuth Access Token
$Headers = @{Authorization = "Bearer $AccessToken"}
$Response = Invoke-RestMethod -Method Get -Uri $APIUri -Headers $Headers 
$Response.value 

GET Method with Multiple Request Headers

In certain scenarios, it may be necessary to include additional request headers alongside the authentication token. The following example demonstrates sending two request headers with the GET method.

$APIUri = "https://graph.microsoft.com/v1.0/users/`$count"
$AccessToken = "eyJ0eXAiOi...." #Replace your OAuth Access Token
$Headers = @{Authorization = "Bearer $AccessToken" ; ConsistencyLevel = "eventual"}
$Response = Invoke-RestMethod -Method Get -Uri $APIUri -Headers $Headers 
$Response

POST Method – Send Data to an API with the POST Request

In the previous examples, we have explored how to use the HTTP GET request method to retrieve information from the server. To send and submit your data to a web server, utilize the POST HTTP request method. We need to provide the input data in the request message body.

The following example creates a new group in Office 365 by sending the group details as JSON body message along with the OAuth Bearer Authentication token with the HTTP POST method.

$APIUri = "https://graph.microsoft.com/v1.0/groups"
$AccessToken = "eyJ0eXAiOi...." #Replace your OAuth Access Token
$Headers = @{Authorization = "Bearer $AccessToken"}


$Data = @{
    "displayName" = "RAPI Test Group11"
    "description" = "Test Group"
    "groupTypes" =  @("Unified")
    "mailEnabled" = $true
    "mailNickname" = "rpaitestgroup11"
    "securityEnabled" = $false
} 

$JsonBody = $Data | ConvertTo-Json

$Response = Invoke-RestMethod -Method POST -Uri $APIUri -Headers $Headers -Body $JsonBody  -ContentType "application/json"
$Response

PATCH Method – Update Details with PATCH Request

The HTTP PATCH request method allows for updating partial details of a resource on the server side. Instead of sending the entire resource data, you can transmit only the details you intend to modify.

In this example, the HTTP PATCH request method is used to modify particular property values (displayName and description) within the existing Office 365 Group object.

$APIUri = "https://graph.microsoft.com/v1.0/groups/37e4df30-5a8f-427b-b307-06971f41e96d"
#$APIUri = "https://graph.microsoft.com/v1.0/groups/{Group-ID}"
$AccessToken = "eyJ0eXAiOi...." #Replace your OAuth Access Token
$Headers = @{Authorization = "Bearer $AccessToken"}

$Data = @{
    "displayName" = "Test Group"
    "description" = "Test Group"    
} 

$JsonBody = $Data | ConvertTo-Json
Invoke-RestMethod -Method PATCH -Uri $APIUri -Headers $Headers -Body $JsonBody  -ContentType "application/json"

DELETE Method – Remove a resource with Delete Request

The following example deletes a group in Office 365.  Simply include the group ID in the request URI, and no additional details need to be sent in the body message.

$APIUri = "https://graph.microsoft.com/v1.0/groups/37e4df30-5a8f-427b-b307-06971f41e96d"
#$APIUri = "https://graph.microsoft.com/v1.0/groups/{Group-ID}"
$AccessToken = "eyJ0eXAiOi...." #Replace your OAuth Access Token

$Headers = @{Authorization = "Bearer $AccessToken"}

Invoke-RestMethod -Method DELETE -Uri $APIUri -Headers $Headers

How to capture HTTP error message when using Invoke-RestAPI

In PowerShell, you may get an HTTP error when you use the Invoke-RestMethod cmdlet to make REST API calls. The Invoke-RestMethod throws an exception without including the details of the HTTP error message from the response body. It is essential to capture the exception object and resolve it to get additional information about the error.

try 
{

$APIUri = "https://graph.microsoft.com/v1.0/groups"
$AccessToken = "eyJ0eXAiOi...." #Replace your OAuth Access Token
$Headers = @{Authorization = "Bearer $AccessToken"}

$Data = @{
    "displayName" = "RAPI Test Group2"
    "description" = "Test Group"
} 

$JsonBody = $Data | ConvertTo-Json

$Response = Invoke-RestMethod -Method POST -Uri $APIUri -Headers $Headers -Body $JsonBody  -ContentType "application/json"

}
catch 
{

if ($_.Exception -is [System.Net.WebException] -AND $_.Exception.Response -ne $null)
{       
  $errorContent = $_.Exception.Response.GetResponseStream()
  $reader = New-Object System.IO.StreamReader($errorContent)
  $errorDetails = $reader.ReadToEnd()
  Write-Host "HTTP error details: $errorDetails" -Foreground "Red"        
}  
else 
{
  Write-Host "An error occurred: $($_.Exception.Message)" -Foreground "Red" 
}
}
Advertisement

Leave a Comment