REST APIs are growing in popularity across many industries, but can PowerShell’s Invoke be used to call these REST APIs directly? This tutorial will walk through the process of calling a REST API from PowerShell.
PowerShell’s Invoke is a command that allows users to work with REST APIs. This tool helps to create, read, update, and delete resources from the web. The “powershell rest api authentication token example” will show how you can use PowerShell’s Invoke to create an authentication token for your REST API.
Do you often use PowerShell to access application programming interfaces (APIs)? Perhaps you want to but aren’t sure where to begin? Whether you’re an experienced PowerShell user or just getting started, this article will show you how to use Invoke-RestMethod, a built-in PowerShell cmdlet that communicates with APIs.
In this tutorial, you’ll learn how to use REST APIs in a variety of ways, including how to use GET and POST queries, how to authenticate, how to download files, and more!
In a Nutshell: Invoke-RestMethod
A client is required when using a REST API to obtain or transmit data. The Invoke-RestMethod cmdlet is the client in the PowerShell universe. This cmdlet performs HTTP queries to REST API endpoints using multiple HTTP methods.
REST APIs are then instructed to perform various actions on a resource using HTTP methods.
Although certain APIs may offer unique methods, the official HTTP methods are GET, HEAD, POST, PUT, DELETE, CONNECT, OPTIONS, TRACE, and PATCH.
The Invoke-RestMethod cmdlet supports all HTTP methods, including authentication, sending various HTTP headers, and sending HTTP contents, as well as automatically converting JSON and XML replies to PowerShell objects. The PowerShell cmdlet Invoke-RestMethod is used to interface with REST APIs.
Prerequisites
If you want to follow along with the various demonstrations in this lesson, make sure you have the following items:
- Installed PowerShell 7.0 or later. This lesson utilizes PowerShell 7.1 and a Windows 10 computer.
Let’s get started by opening your PowerShell console and/or code editor.
Data Retrieval Using a Simple GET Request
Let’s start with the most basic example available: using a GET request to query a REST API. You can accomplish a lot with Invoke-RestMethod, but you need to know the fundamentals first.
Only one argument, Uri, is required to submit a basic GET request to a REST API endpoint. The Uri option instructs Invoke-RestMethod where to look for the endpoint.
Run the command below, for example. This command gets a list of post resources from the JSONPlaceholder API’s posts endpoint.
The JSONPlaceholder site provides a free dummy API for testing, which is used to provide real-world instances of Invoke-RestMethod requests.
Invoke-RestMethod -Uri “https://jsonplaceholder.typicode.com/posts” Invoke-RestMethod -Uri “https://jsonplaceholder.typicode.com/posts”
JSONPlaceholder API posts endpoint partial output.
The data sent by the REST API https://jsonplaceholder.typicode.com/posts is not in beautiful PowerShell objects, as seen above. Instead, it returns JSON data. The JSON was automatically transformed to PowerShell objects by Invoke-RestMethod.
PowerShell transformed the result to the PSCustomObject type by inspecting a single item in the PowerShell array and using the GetType() function on it, as shown below.
ArrayLists and Arrays in PowerShell Can Help You Write Better Scripts
# Store the API GET response in a variable ($Posts). $Posts = Invoke-RestMethod -Uri “https://jsonplaceholder.typicode.com/posts” Invoke-RestMethod -Uri “https://jsonplaceholder.typicode.com/posts” # Run the GetType() method against the first item in the array, identified by its index of 0. $Posts[0].GetType()
The automated translation of the JSON answer to PowerShell’s PSCustomObject type is seen in the output.
Using an API to authenticate yourself
You used the GET technique to query a public REST API in the previous section. There was no need for authentication using the API. However, you must often authenticate to a REST API in some way.
Basic (username/password) and Bearer (token) authentication are two of the most frequent methods to authenticate to a REST API. When submitting a request, use an Authorization HTTP header to distinguish between these two drastically different authentication techniques.
Let’s look at how you can utilize Invoke-RestMethod to deliver HTTP headers to REST endpoints, particularly the Authorization HTTP header.
The Invoke-RestMethod takes care of a lot of the tedious aspects of making HTTP requests. Despite the fact that an HTTP request must include an Authorization header, there are no references to “headers” in this example. The Invoke-RestMethod cmdlet is used to abstract away ideas like these.
Basic Authentication with a Username and Password
Using a username and password to authenticate to a REST API is the simplest method. You must give a PSCredential object with the login and password to the endpoint in order to collect it.
Using the Get-Credential Cmdlet in PowerShell and all things credentials
Create the PSCredential object first, which will include the login and password.
# This will request credentials and save them in a PSCredential object. Get-Credential $Cred = Get-Credential $Cred = Get-Credential $C
Once you’ve created a PSCredential object in a variable, run the program again, but this time include the Authentication and Credential parameters.
When the Authentication option is set to Basic, an authorization HTTP header with the word Basic and a base64 encoded username:password string like Authorization: Basic is sent. ZGVtbzpwQDU1dzByZA==.
The PSCredential you established before is accepted by the Credential argument.
The example below, as well as many others in this article, employs a technique known as PowerShell splatting, which enables you to create arguments in a hashtable and then give them to the command. In the ATA article PowerShell Splatting: What Is It and How Does It Work?, you can learn more about splatting.
# Make a GET request with Basic authentication included. $Params = @ Uri = “https://jsonplaceholder.typicode.com/posts” Authentication = “Basic” Credential = $Cred Authentication = “Basic” Credential = $Cred Authentication = “Basic” @Params Invoke-RestMethod
Using basic authentication, partial output from the JSONPlaceholder API posts endpoint.
For security concerns, Invoke-RestMethod will return an error if you use the Credential or Authentication parameter option with a Uri that does not begin with https://. Use the AllowUnencryptedAuthentication argument at your own risk to alter this default behavior.
Bearer Authentication using an API/OAuth Token
Basic username and password authentication is acceptable, but not exceptional. Credentials are just base64 encoded (not encrypted), which raises security concerns. APIs often use a token authentication scheme or Bearer/OAuth authentication to handle this.
To use an OAuth token to access a REST API, follow these steps:
1. Retrieve your API’s OAuth token. Your API provider will choose how you receive this token.
2. Next, use the ConvertTo-SecureString cmdlet to convert your token string to a secure string, as illustrated below. The token must be a secure string for the Invoke-RestMethod to work.
$Token = “123h1v23yt2egv1e1e1b2ei1ube2iu12be” | ConvertTo-SecureString -AsPlainText -Force $Token = “123h1v23yt2egv1e1e1b2ei1ube2iu12be”
3. Finally, use the Invoke-RestMethod cmdlet to specify and supply the Uri, Authentication type, and Token. The token will be added to the Authorization HTTP header by Invoke-RestMethod, which will subsequently call the URI specified.
OAuth is an alias for Bearer in the Authentication parameter argument. Both of these parameter values may be used interchangeably.
# Make a GET request with bearer authentication included. $Params = @ Uri = “https://jsonplaceholder.typicode.com/posts” Authentication = “Bearer” Token = $Token Authentication = “Bearer” Token = $Token Authentication = “Bearer” Token = $Token Authentication = “Bearer” Token = $Token Authentication = “Bearer” To @Params Invoke-RestMethod
Using bearer token authentication, partial output from JSONPlaceholder API publishes endpoint.
Using Query Parameters to Retrieve Data
A GET request to a REST API is usually more complicated than a basic, general request to an endpoint. Instead, you must supply parameters to the API to define precisely what you want; you must pass HTTP query parameters.
There are two ways to transmit query parameters with Invoke-RestMethod. You may attach the arguments to the URI directly, as seen below, which sends a userId of 1 and an id of 8 to the URI.
https://jsonplaceholder.typicode.com/posts?userId=1&id=8
You may also use the Body parameter as a hashtable to specify the parameters in the HTTP body. Let’s look at how to use the Body parameter to deliver arguments to an endpoint.
Assemble a hashtable using the query parameter key/value pairs as shown below.
$Body = @ userId = 1 id = 8 $Body = @ userId = 1 id = 8 $Body = @ userId = 1 id
Finally, as seen below, provide the $Body variable to the Body argument.
You may use the value GET to define the Method argument, or you can leave it blank or use Invoke-RestMethod to default to the value.
$Params = @ Method = “Get” Uri = “https://jsonplaceholder.typicode.com/posts” Body = $Body Invoke-RestMethod @Params @Params @Params @Params @Params @Params @Params @Params @Params @Params @Params @Params @Params @Params @Params @Params @Par
The endpoint now only returns the post item you’re searching for, as you can see below.
Using Invoke-RestMethod to query API using HTTP query parameters
Using the POST HTTP Method to Send Data to an API
You were requesting data from a REST API or making HTTP GET queries in the previous cases. You were reading the data it returned, but with many REST APIs, reading is just half the story. To interact with a service, REST APIs must provide a complete CRUD model.
You won’t use a GET HTTP request to make modifications to a service that provides an API; instead, you’ll use a “writable” request like POST.
When utilizing any “writable” HTTP method like PUT or PATCH, you’ll often need to send an HTTP body with your requests.
Using a POST Request to Send JSON Data
Let’s generate a new post item instead of merely reading them using the prior REST API endpoint.
Create a hashtable with all of the properties for the posts API endpoint first. The tutorial’s particular endpoint enables you to create a new post item with a title, body, and userId, as seen below.
$Body = @ title = “foo” body = “bar” $Body = @ title = “foo” body = “bar” userId = 1 userId = 1 userId = 1 userId = 1 user
2. Next, transform the hashtable in the $Body variable to a JSON string and save it in the $JsonBody variable.
Endpoints of the REST protocol You don’t know what a PowerShell hashtable is, and you need to translate it to a language that the REST API can comprehend. It’s not necessary to create a hashtable initially. If you wanted to, you could input the JSON directly and skip this step.
$Body | ConvertTo-Json $JsonBody = $Body
3. Finally, use Invoke-RestMethod with the appropriate arguments. You’ll see that the Method parameter must now be set to Post in the example below. Invoke-RestMethod defaults to make a GET request if the Method option is not specified.
Many REST APIs also need you to give the ContentType, which specifies the HTTP Content-Type header in which the Body is stored. You must use application/json in this case.
Unless otherwise provided, the ContentType for all POST requests will be set to application/x-www-form-urlencoded. @ $Params $Params $Params $Params $Par Body = $JsonBody ContentType = “application/json” Method = “Post” Uri = “https://jsonplaceholder.typicode.com/posts” @Params Invoke-RestMethod
The API produces a post item along with an id for the new post, as seen below.
Using Invoke-RestMethod to send a JSON POST
Using Invoke-RestMethod to Send Form Data
You may be required to send data using the multipart/form-data HTTP content type for certain REST API calls. It’s a little simpler to submit a different content type with Invoke-RestMethod than it is with JSON. The Form parameter is now available in PowerShell 6.1.0.
The Form parameter makes it easy to add multipart/form-data objects to a request without having to utilize the.NET Framework. Directly using the Net.Http.MultipartFormDataContent class.
To use Invoke-RestMethod to deliver form data, first establish a hashtable with each item like before.
$Form = @ title = “foo” body = “bar” userId = 1 userId = 1 userId = 1 userId = 1 userId = 1 userId = 1 userId = 1 userId = 1
You should use the Form parameter instead of the Body parameter. Invoke-RestMethod will also disregard the ContentType argument if you try to supply both the ContentType and the Form parameters at the same time.
Finally, as illustrated below, send the hashtable to the Form argument.
@ $Params $Params $Params $Params $Par “https://jsonplaceholder.typicode.com/posts” Uri = “https://jsonplaceholder.typicode.com/posts” Form = $Form @Params Invoke-RestMethod
Using the Invoke-RestMethod cmdlet to submit a Form Content type
Relationship Links to Follow
APIs often deliver “pages” of data rather than large datasets all at once. The GitHub Problems API, for example, provides 30 issues per page by default. Relation links, which are included in certain API responses to aid browse the dataset, are links to the next (or previous, final, etc.) page of data.
The HTTP response headers must be examined to detect related links sent by an API. The ResponseHeadersVariable argument is one simple method to do this. This argument creates a variable and saves the headers in a hashtable automatically.
Let’s look at the problems in the PowerShell GitHub repo as an example.
1. Make a GET call to the problems endpoint of the PowerShell GitHub project, as illustrated below. To construct a variable, be sure to utilize the ResponseHeadersVariable. The $Headers variable is used in the example below.
# Make a GET call to the GitHub problems API for the PowerShell project repo, then save the return headers in a variable ($Headers). -Uri “https://api.github.com/repos/powershell/powershell/issues” -ResponseHeadersVariable “Headers” Invoke-RestMethod -Uri “https://api.github.com/repos/powershell/powershell/issues” -ResponseHeadersVariable “Headers” # To the terminal, print the $Headers variable. $Headers
The hashtable within the $Headers variable contains a key named Links, as seen below. This key holds the answer’s related connections, indicating that the data set is larger than simply this one response.
Request headers for the GitHub issues API, displaying related connections.
2. Next, use the FollowRelLink argument to follow the relation connections. This option scans each of the related links and sends a GET request to each of them automatically.
The code line below will follow each related connection up to three times. The Invoke-RestMethod cmdlet will stop inquiring for problems when it reaches 90 (30 items per request) in this case.
@ Uri = “https://api.github.com/repos/powershell/powershell/issues” $Params = @ Uri = “https://api.github.com/repos/powershell/powershell/issues” MaximumFollowRelLink = 3 FollowRelLink = $true @Params Invoke-RestMethod
Invoke-RestMethod delivers an array of objects when the FollowRelLink argument is used (Object[]). Each item in the array represents the answer from one of the related connections, which may be a separate array of objects!
Use the FollowRelLink argument to get a partial response from a call to the GitHub problems API.
3. Rerun the same example, but this time look at the original query’s returned results. There will only be three “pages” as indicated by the count of three. However, you’ll see that the first page of results ($Results[0]) has 30 items.
@ Uri = “https://api.github.com/repos/powershell/powershell/issues” $Params = @ Uri = “https://api.github.com/repos/powershell/powershell/issues” MaximumFollowRelLink = 3 FollowRelLink = $true # In the $Results variable, save the three pages of results. @Params $Results = Invoke-RestMethod # Make sure $Results has three items (pages of issues from the GitHub issues API). $Results.Count # Make sure the first item in the $Results array contains the first page of each of the thirty issues. $Results[0].Count
The nested arrays provided by the FollowRelLink option are shown in the output.
4. Finally, use a foreach loop to go through each item in the $Results variable. You’ll see below that you’ll need to use a foreach loop to traverse through each page. Then, for each page, use a nested loop to iterate through all of the elements on that page.
Back to the Basics with PowerShell’s ForEach Loop
# Depending on the data format of the API you’re using, this might be different. $Results.ForEach() cycles over all of the pages in the $Results array. # 2)
Do you often use PowerShell to access application programming interfaces (APIs)? Perhaps you want to but aren’t sure where to begin? Whether you’re an experienced PowerShell user or just getting started, this article will show you how to use Invoke-RestMethod, a built-in PowerShell cmdlet that communicates with APIs.
In this tutorial, you’ll learn how to use REST APIs in a variety of ways, including how to use GET and POST queries, how to authenticate, how to download files, and more!
In a Nutshell: Invoke-RestMethod
A client is required when using a REST API to obtain or transmit data. The Invoke-RestMethod cmdlet is the client in the PowerShell universe. This cmdlet performs HTTP queries to REST API endpoints using multiple HTTP methods.
REST APIs are then instructed to perform various actions on a resource using HTTP methods.
Although certain APIs may offer unique methods, the official HTTP methods are GET, HEAD, POST, PUT, DELETE, CONNECT, OPTIONS, TRACE, and PATCH.
The Invoke-RestMethod cmdlet supports all HTTP methods, including authentication, sending various HTTP headers, and sending HTTP contents, as well as automatically converting JSON and XML replies to PowerShell objects. The PowerShell cmdlet Invoke-RestMethod is used to interface with REST APIs.
Prerequisites
If you want to follow along with the various demonstrations in this lesson, make sure you have the following items:
- Installed PowerShell 7.0 or later. This lesson utilizes PowerShell 7.1 and a Windows 10 computer.
Let’s get started by opening your PowerShell console and/or code editor.
Data Retrieval Using a Simple GET Request
Let’s start with the most basic example available: using a GET request to query a REST API. You can accomplish a lot with Invoke-RestMethod, but you need to know the fundamentals first.
Only one argument, Uri, is required to submit a basic GET request to a REST API endpoint. The Uri option instructs Invoke-RestMethod where to look for the endpoint.
Run the command below, for example. This command gets a list of post resources from the JSONPlaceholder API’s posts endpoint.
The JSONPlaceholder site provides a free dummy API for testing, which is used to provide real-world instances of Invoke-RestMethod requests.
Invoke-RestMethod -Uri “https://jsonplaceholder.typicode.com/posts” Invoke-RestMethod -Uri “https://jsonplaceholder.typicode.com/posts”
JSONPlaceholder API posts endpoint partial output.
The data sent by the REST API https://jsonplaceholder.typicode.com/posts is not in beautiful PowerShell objects, as seen above. Instead, it returns JSON data. The JSON was automatically transformed to PowerShell objects by Invoke-RestMethod.
PowerShell transformed the result to the PSCustomObject type by inspecting a single item in the PowerShell array and using the GetType() function on it, as shown below.
ArrayLists and Arrays in PowerShell Can Help You Write Better Scripts
# Store the API GET response in a variable ($Posts). $Posts = Invoke-RestMethod -Uri “https://jsonplaceholder.typicode.com/posts” Invoke-RestMethod -Uri “https://jsonplaceholder.typicode.com/posts” # Run the GetType() method against the first item in the array, identified by its index of 0. $Posts[0].GetType()
The automated translation of the JSON answer to PowerShell’s PSCustomObject type is seen in the output.
Using an API to authenticate yourself
You used the GET technique to query a public REST API in the previous section. There was no need for authentication using the API. However, you must often authenticate to a REST API in some way.
Basic (username/password) and Bearer (token) authentication are two of the most frequent methods to authenticate to a REST API. When submitting a request, use an Authorization HTTP header to distinguish between these two drastically different authentication techniques.
Let’s look at how you can utilize Invoke-RestMethod to deliver HTTP headers to REST endpoints, particularly the Authorization HTTP header.
The Invoke-RestMethod takes care of a lot of the tedious aspects of making HTTP requests. Despite the fact that an HTTP request must include an Authorization header, there are no references to “headers” in this example. The Invoke-RestMethod cmdlet is used to abstract away ideas like these.
Basic Authentication with a Username and Password
Using a username and password to authenticate to a REST API is the simplest method. You must give a PSCredential object with the login and password to the endpoint in order to collect it.
Using the Get-Credential Cmdlet in PowerShell and all things credentials
Create the PSCredential object first, which will include the login and password.
# This will request credentials and save them in a PSCredential object. Get-Credential $Cred = Get-Credential $Cred = Get-Credential $C
Once you’ve created a PSCredential object in a variable, run the program again, but this time include the Authentication and Credential parameters.
When the Authentication option is set to Basic, an authorization HTTP header with the word Basic and a base64 encoded username:password string like Authorization: Basic is sent. ZGVtbzpwQDU1dzByZA==.
The PSCredential you established before is accepted by the Credential argument.
The example below, as well as many others in this article, employs a technique known as PowerShell splatting, which enables you to create arguments in a hashtable and then give them to the command. In the ATA article PowerShell Splatting: What Is It and How Does It Work?, you can learn more about splatting.
# Make a GET request with Basic authentication included. $Params = @ Uri = “https://jsonplaceholder.typicode.com/posts” Authentication = “Basic” Credential = $Cred Authentication = “Basic” Credential = $Cred Authentication = “Basic” @Params Invoke-RestMethod
Using basic authentication, partial output from the JSONPlaceholder API posts endpoint.
For security concerns, Invoke-RestMethod will return an error if you use the Credential or Authentication parameter option with a Uri that does not begin with https://. Use the AllowUnencryptedAuthentication argument at your own risk to alter this default behavior.
Bearer Authentication using an API/OAuth Token
Basic username and password authentication is acceptable, but not exceptional. Credentials are just base64 encoded (not encrypted), which raises security concerns. APIs often use a token authentication scheme or Bearer/OAuth authentication to handle this.
To use an OAuth token to access a REST API, follow these steps:
1. Retrieve your API’s OAuth token. Your API provider will choose how you receive this token.
2. Next, use the ConvertTo-SecureString cmdlet to convert your token string to a secure string, as illustrated below. The token must be a secure string for the Invoke-RestMethod to work.
$Token = “123h1v23yt2egv1e1e1b2ei1ube2iu12be” | ConvertTo-SecureString -AsPlainText -Force $Token = “123h1v23yt2egv1e1e1b2ei1ube2iu12be”
3. Finally, use the Invoke-RestMethod cmdlet to specify and supply the Uri, Authentication type, and Token. The token will be added to the Authorization HTTP header by Invoke-RestMethod, which will subsequently call the URI specified.
OAuth is an alias for Bearer in the Authentication parameter argument. Both of these parameter values may be used interchangeably.
# Make a GET request with bearer authentication included. $Params = @ Uri = “https://jsonplaceholder.typicode.com/posts” Authentication = “Bearer” Token = $Token Authentication = “Bearer” Token = $Token Authentication = “Bearer” Token = $Token Authentication = “Bearer” Token = $Token Authentication = “Bearer” To @Params Invoke-RestMethod
Using bearer token authentication, partial output from JSONPlaceholder API publishes endpoint.
Using Query Parameters to Retrieve Data
A GET request to a REST API is usually more complicated than a basic, general request to an endpoint. Instead, you must supply parameters to the API to define precisely what you want; you must pass HTTP query parameters.
There are two ways to transmit query parameters with Invoke-RestMethod. You may attach the arguments to the URI directly, as seen below, which sends a userId of 1 and an id of 8 to the URI.
https://jsonplaceholder.typicode.com/posts?userId=1&id=8
You may also use the Body parameter as a hashtable to specify the parameters in the HTTP body. Let’s look at how to use the Body parameter to deliver arguments to an endpoint.
Assemble a hashtable using the query parameter key/value pairs as shown below.
$Body = @ userId = 1 id = 8 $Body = @ userId = 1 id = 8 $Body = @ userId = 1 id
Finally, as seen below, provide the $Body variable to the Body argument.
You may use the value GET to define the Method argument, or you can leave it blank or use Invoke-RestMethod to default to the value.
$Params = @ Method = “Get” Uri = “https://jsonplaceholder.typicode.com/posts” Body = $Body Invoke-RestMethod @Params @Params @Params @Params @Params @Params @Params @Params @Params @Params @Params @Params @Params @Params @Params @Params @Par
The endpoint now only returns the post item you’re searching for, as you can see below.
Using Invoke-RestMethod to query API using HTTP query parameters
Using the POST HTTP Method to Send Data to an API
You were requesting data from a REST API or making HTTP GET queries in the previous cases. You were reading the data it returned, but with many REST APIs, reading is just half the story. To interact with a service, REST APIs must provide a complete CRUD model.
You won’t use a GET HTTP request to make modifications to a service that provides an API; instead, you’ll use a “writable” request like POST.
When utilizing any “writable” HTTP method like PUT or PATCH, you’ll often need to send an HTTP body with your requests.
Using a POST Request to Send JSON Data
Let’s generate a new post item instead of merely reading them using the prior REST API endpoint.
Create a hashtable with all of the properties for the posts API endpoint first. The tutorial’s particular endpoint enables you to create a new post item with a title, body, and userId, as seen below.
$Body = @ title = “foo” body = “bar” $Body = @ title = “foo” body = “bar” userId = 1 userId = 1 userId = 1 userId = 1 user
2. Next, transform the hashtable in the $Body variable to a JSON string and save it in the $JsonBody variable.
Endpoints of the REST protocol You don’t know what a PowerShell hashtable is, and you need to translate it to a language that the REST API can comprehend. It’s not necessary to create a hashtable initially. If you wanted to, you could input the JSON directly and skip this step.
$Body | ConvertTo-Json $JsonBody = $Body
3. Finally, use Invoke-RestMethod with the appropriate arguments. You’ll see that the Method parameter must now be set to Post in the example below. Invoke-RestMethod defaults to make a GET request if the Method option is not specified.
Many REST APIs also need you to give the ContentType, which specifies the HTTP Content-Type header in which the Body is stored. You must use application/json in this case.
Unless otherwise provided, the ContentType for all POST requests will be set to application/x-www-form-urlencoded. @ $Params $Params $Params $Params $Par Body = $JsonBody ContentType = “application/json” Method = “Post” Uri = “https://jsonplaceholder.typicode.com/posts” @Params Invoke-RestMethod
The API produces a post item along with an id for the new post, as seen below.
Using Invoke-RestMethod to send a JSON POST
Using Invoke-RestMethod to Send Form Data
You may be required to send data using the multipart/form-data HTTP content type for certain REST API calls. It’s a little simpler to submit a different content type with Invoke-RestMethod than it is with JSON. The Form parameter is now available in PowerShell 6.1.0.
The Form parameter makes it easy to add multipart/form-data objects to a request without having to utilize the.NET Framework. Directly using the Net.Http.MultipartFormDataContent class.
To use Invoke-RestMethod to deliver form data, first establish a hashtable with each item like before.
$Form = @ title = “foo” body = “bar” userId = 1 userId = 1 userId = 1 userId = 1 userId = 1 userId = 1 userId = 1 userId = 1
You should use the Form parameter instead of the Body parameter. Invoke-RestMethod will also disregard the ContentType argument if you try to supply both the ContentType and the Form parameters at the same time.
Finally, as illustrated below, send the hashtable to the Form argument.
@ $Params $Params $Params $Params $Par “https://jsonplaceholder.typicode.com/posts” Uri = “https://jsonplaceholder.typicode.com/posts” Form = $Form @Params Invoke-RestMethod
Using the Invoke-RestMethod cmdlet to submit a Form Content type
Relationship Links to Follow
APIs often deliver “pages” of data rather than large datasets all at once. The GitHub Problems API, for example, provides 30 issues per page by default. Relation links, which are included in certain API responses to aid browse the dataset, are links to the next (or previous, final, etc.) page of data.
The HTTP response headers must be examined to detect related links sent by an API. The ResponseHeadersVariable argument is one simple method to do this. This argument creates a variable and saves the headers in a hashtable automatically.
Let’s look at the problems in the PowerShell GitHub repo as an example.
1. Make a GET call to the problems endpoint of the PowerShell GitHub project, as illustrated below. To construct a variable, be sure to utilize the ResponseHeadersVariable. The $Headers variable is used in the example below.
# Make a GET call to the GitHub problems API for the PowerShell project repo, then save the return headers in a variable ($Headers). -Uri “https://api.github.com/repos/powershell/powershell/issues” -ResponseHeadersVariable “Headers” Invoke-RestMethod -Uri “https://api.github.com/repos/powershell/powershell/issues” -ResponseHeadersVariable “Headers” # To the terminal, print the $Headers variable. $Headers
The hashtable within the $Headers variable contains a key named Links, as seen below. This key holds the answer’s related connections, indicating that the data set is larger than simply this one response.
Request headers for the GitHub issues API, displaying related connections.
2. Next, use the FollowRelLink argument to follow the relation connections. This option scans each of the related links and sends a GET request to each of them automatically.
The code line below will follow each related connection up to three times. The Invoke-RestMethod cmdlet will stop inquiring for problems when it reaches 90 (30 items per request) in this case.
@ Uri = “https://api.github.com/repos/powershell/powershell/issues” $Params = @ Uri = “https://api.github.com/repos/powershell/powershell/issues” MaximumFollowRelLink = 3 FollowRelLink = $true @Params Invoke-RestMethod
Invoke-RestMethod delivers an array of objects when the FollowRelLink argument is used (Object[]). Each item in the array represents the answer from one of the related connections, which may be a separate array of objects!
Use the FollowRelLink argument to get a partial response from a call to the GitHub problems API.
3. Rerun the same example, but this time look at the original query’s returned results. There will only be three “pages” as indicated by the count of three. However, you’ll see that the first page of results ($Results[0]) has 30 items.
@ Uri = “https://api.github.com/repos/powershell/powershell/issues” $Params = @ Uri = “https://api.github.com/repos/powershell/powershell/issues” MaximumFollowRelLink = 3 FollowRelLink = $true # In the $Results variable, save the three pages of results. @Params $Results = Invoke-RestMethod # Make sure $Results has three items (pages of issues from the GitHub issues API). $Results.Count # Make sure the first item in the $Results array contains the first page of each of the thirty issues. $Results[0].Count
The nested arrays provided by the FollowRelLink option are shown in the output.
4. Finally, use a foreach loop to go through each item in the $Results variable. You’ll see below that you’ll need to use a foreach loop to traverse through each page. Then, for each page, use a nested loop to iterate through all of the elements on that page.
Back to the Basics with PowerShell’s ForEach Loop
# This might be different depending on the data structure of the API you are using. # 1) $Results.ForEach({}) – this loops through each page in the $Results array. # 2) $_.ForEach({}) – this loops through each item in the current page. # 3) $_ – this simply returns each item to the pipeline. $AllResults = @( $Results.ForEach({ $_.ForEach({ $_ }) }) ) # Check that the $AllResults variable contains all ninety items. $AllResults.Count
In a single array ($AllResults), the output shows all ninety GitHub problems.
Keeping Track of Session Data
When dealing with APIs, it’s common to save data from prior requests, such as headers, credentials, proxy information, and cookies, to reuse in later queries. A session is where all of this data is saved.
By saving the session using the SessionVariable argument and subsequently referencing it with the WebSession parameter, the Invoke-RestMethod may take use of sessions.
To illustrate, utilize the SessionVariable argument when using the posts endpoint, as seen below. Invoke-RestMethod will generate a variable named MySession in this case.
The session object isn’t a permanent connection, so keep that in mind. A session is nothing more than an object that stores information about the request.
# Invoke the request storing the session as MySession. # The SessionVariable value shouldn’t include a dollar sign ($). Invoke-RestMethod -Uri “https://jsonplaceholder.typicode.com/posts” Invoke-RestMethod -Uri “https://jsonplaceholder.typicode.com/posts” -SessionVariable “MySession” # Print the session object to the console. $MySession
The session object attributes are shown in the output.
Now, run Invoke-RestMethod with the WebSession option to reuse the session information. As you can see in the following example, all prior session data are given through the $MySession variable in the new request.
# Invoke the request using the session information stored in the $MySession variable. Invoke-RestMethod -Uri “https://jsonplaceholder.typicode.com/posts” Invoke-RestMethod -Uri “https://jsonplaceholder.typicode.com/posts” -WebSession $MySession
A portion of the output demonstrating the reuse of a previously saved session ($MySession).
Session Values That Take Priority
A session is a collection of data about a request. You can override the session if you wish to reuse it but alter a value.
You could want to re-use a previously established session, but this time login using a username and password. Let’s take a look at the current scenario first.
The Credentials attribute of the $MySession object has no value, as you can see below. However, even though the credential was not in the session, the REST endpoint gets it after running Invoke-RestMethod again with the Credential option.
# To show that the Credentials # field is empty, print the $MySession variable to the console. $MySession # Specify the Credential argument to override the session value. # In this case, you’ll be asked to enter your login and password. WebSession = $MySession Credential = (Get-Credential) $Params = @ Uri = “https://jsonplaceholder.typicode.com/posts” @Params Invoke-RestMethod
The parameter name is Credential, whereas the property name in the stored session is Credential. It is not usually the case that the names are identical.
Specifying the Credential option overrides the Credentials value in the session variable ($MySession).
Creating a File with the Response Body
It may be required to store the answer to a request to a file at times. Use the OutFile argument to do this.
Use the OutFile option and supply a file location to query the tutorial’s testing endpoint again using Invoke-RestMethod.
Invoke-RestMethod requests the endpoint, returns the response in JSON format, and stores the raw JSON into the.my-posts.json file, as seen below.
You may also use the PassThru option to save a file with the answer and return it to the console at the same time.
# Save post items to my-posts.json in the current directory. Invoke-RestMethod -Uri “https://jsonplaceholder.typicode.com/posts” Invoke-RestMethod -Uri “https://jsonplaceholder.typicode.com/posts” -OutFile “my-posts.json” # Print the contents of the JSON file to the console. # “.” in this command refers to the current working directory in your terminal session. Get-Content -Path “.my-posts.json”
The contents of my-posts are only partially output. json.
After you’ve stored the answer as JSON in a file, you may parse it for data as needed. A nice example of locating a post with a given ID can be seen below.
# Save the response to “my-posts.json” and also in the $Posts variable using PassThru. $Posts = Invoke-RestMethod -Uri “https://jsonplaceholder.typicode.com/posts” Invoke-RestMethod -Uri “https://jsonplaceholder.typicode.com/posts” -OutFile “my-posts.json” -PassThru # Filter posts with 1 as the userId into a new variable ($User1Posts). $User1Posts = $Posts.Where({$_.userId -eq 1}) # Import all posts from the “my-posts.json” file and store them in the $AllUserPosts variable. $AllUserPosts = Get-Content -Path “.my-posts.json” | ConvertFrom-Json # Print the count of both variables to the console to demonstrate that they are different. $User1Posts.Count $AllUserPosts.Count
Output demonstrating how to use PassThru to save results in both a variable and a file inside the same command.
When it comes to SSL and certificates, there are a few things to keep in mind.
You’ve solely worked with HTTP throughout this lesson. There hasn’t been any mention of HTTPS or SSL. But it doesn’t rule out the possibility of using Invoke-RestMethod with SSL. In fact, it can handle almost any task you throw at it.
Validation of Certificates is skipped.
By default, Invoke-RestMethod verifies the certificate of any SSL site to confirm that it is not expired, revoked, or that the trust chain is intact. Although this is a security feature that you should keep enabled, there are instances when you need to deactivate it, such as during testing.
Creating Certificates using PowerShell: New-SelfSignedCertificate
Use the SkipCertificateCheck option to bypass certificate validation. This argument disables all certificate checking that is normally performed by Invoke-RestMethod.
Specifying a Request’s Client Certificate
Use the Certificate argument of Invoke-RestMethod to provide a client certificate for a specific request. This argument accepts an X509Certificate object as its value, which you may get from the Cert: PSDrive using the Get-PfxCertificate or Get-ChildItem commands.
The following command, for example, makes a call to the JSONPlaceholder APIs posts endpoint using a certificate from the Cert: drive.
# Change location into your personal certificate store. Set-Location “Cert:CurrentUserMy” # Store the certificate with the thumbprint DDE2EC6DBFF56EE9C375A6073C97188ABAA4F5E4 in a variable ($Cert). $Cert = Get-ChildItem | Where-Object {$_.Thumbprint -eq “DDE2EC6DBFF56EE9C375A6073C97188ABAA4F5E4”} # Invoke the command using the client certificate. Invoke-RestMethod -Uri “https://jsonplaceholder.typicode.com/posts” Invoke-RestMethod -Uri “https://jsonplaceholder.typicode.com/posts” -Certificate $Cert
When performing a GET request, use a client certificate.
SSL/TLS Protocol Restrictions
All SSL/TLS protocols supported by your system are enabled by default. Use the SslProtocol argument if you need to limit a request to a certain protocol version(s).
You may call a URI with a version of TLS from v1, 1.1, 1.2, and 1.3 as an array using the SslProtocol.
# Restrict the request to only allow SSL/TLS 1.2 and 1.3 protocol versions. Invoke-RestMethod -Uri “https://jsonplaceholder.typicode.com/posts” Invoke-RestMethod -Uri “https://jsonplaceholder.typicode.com/posts” -SslProtocol @(“Tls12”, “Tls13”)
Tls or Tls12 may not be available on non-Windows systems. Tls13 support isn’t accessible on all operating systems, therefore it’ll have to be checked on a case-by-case basis. Tls13 is only accessible in PowerShell 7.1 and later versions.
Other Interesting Characteristics
Let’s finish off this lesson with a few important parameters that don’t necessary need an instruction section.
Making Use of a Proxy Server
Proxy servers are often used in corporate organizations to regulate internet access. Use the Proxy argument to compel Invoke-RestMethod to proxy its request via a proxy.
If you need to authenticate to the proxy, either provide a PSCredential object to the ProxyCredential argument or use the ProxyUseDefaultCredentials switch option to use the credentials of the currently logged-on user.
# Invoke request using proxy server <http://10.0.10.1:8080> and the current user’s credentials. Invoke-RestMethod -Uri “https://jsonplaceholder.typicode.com/posts” Invoke-RestMethod -Uri “https://jsonplaceholder.typicode.com/posts” -Proxy “http://10.0.10.1:8080” -ProxyUseDefaultCredentials
Checks and Validation are being skipped.
You may be exposed to security concerns if you use these settings. You have been forewarned.
The Invoke-RestMethod cmdlet performs a variety of tests behind the scenes. You may deactivate these tests with a few options if you want to for whatever reason.
- SkipHeaderValidation — Turns off validation for the ContentType, Headers, and UserAgent parameters’ values.
- Any errors will be ignored if you use SkipHttpErrorCheck. Before processing proceeds, the error will be sent to the pipeline.
- When using SkipHttpErrorCheck, you may need to examine the HTTP response status code to determine whether the message is a success or failure. For this reason, the StatusCodeVariable option will give the status code integer value to a variable.
Keep Alive is disabled.
TCP Keep Alive is a useful network function that enables you to keep a connection to a distant server alive (if the server supports it). Keep Alive is not used by default in Invoke-RestMethod.
Set the DisableKeepAlive argument to $false if you want to utilize Keep Alive to possibly reduce the remote server’s CPU and memory use.
Invoke-RestMethod -Uri “https://jsonplaceholder.typicode.com/posts” -Uri “https://jsonplaceholder.typicode.com/posts” -DisableKeepAlive $false Invoke-RestMethod
Changing the Type of Encoding
When Invoke-RestMethod delivers a request to a remote endpoint, it uses a transfer-encoding header to encode the request. By default, Invoke-RestMethod and the server negotiate the encoding method, but you may use the TransferEncoding argument to specify an encoding type manually.
If you want to change the encoding type, use the following commands:
- Chunked
- Compress
- Deflate
- GZip
- Identity
Conclusion
You’ve seen how Invoke-RestMethod makes communicating with REST APIs considerably simpler than normal web requests in this lesson. You’ve studied parameters for authentication, sending data in the body of a request, keeping session state, downloading files, and more.
What REST API would you test this handy cmdlet on now that you’re up to speed on Invoke-RestMethod and dealing with REST APIs?
.ForEach() – cycles over all of the items on the current page. # 3) $ – this just adds each item to the pipeline. @ $AllResults ($Results.ForEach(
Do you often use PowerShell to access application programming interfaces (APIs)? Perhaps you want to but aren’t sure where to begin? Whether you’re an experienced PowerShell user or just getting started, this article will show you how to use Invoke-RestMethod, a built-in PowerShell cmdlet that communicates with APIs.
In this tutorial, you’ll learn how to use REST APIs in a variety of ways, including how to use GET and POST queries, how to authenticate, how to download files, and more!
In a Nutshell: Invoke-RestMethod
A client is required when using a REST API to obtain or transmit data. The Invoke-RestMethod cmdlet is the client in the PowerShell universe. This cmdlet performs HTTP queries to REST API endpoints using multiple HTTP methods.
REST APIs are then instructed to perform various actions on a resource using HTTP methods.
Although certain APIs may offer unique methods, the official HTTP methods are GET, HEAD, POST, PUT, DELETE, CONNECT, OPTIONS, TRACE, and PATCH.
The Invoke-RestMethod cmdlet supports all HTTP methods, including authentication, sending various HTTP headers, and sending HTTP contents, as well as automatically converting JSON and XML replies to PowerShell objects. The PowerShell cmdlet Invoke-RestMethod is used to interface with REST APIs.
Prerequisites
If you want to follow along with the various demonstrations in this lesson, make sure you have the following items:
- Installed PowerShell 7.0 or later. This lesson utilizes PowerShell 7.1 and a Windows 10 computer.
Let’s get started by opening your PowerShell console and/or code editor.
Data Retrieval Using a Simple GET Request
Let’s start with the most basic example available: using a GET request to query a REST API. You can accomplish a lot with Invoke-RestMethod, but you need to know the fundamentals first.
Only one argument, Uri, is required to submit a basic GET request to a REST API endpoint. The Uri option instructs Invoke-RestMethod where to look for the endpoint.
Run the command below, for example. This command gets a list of post resources from the JSONPlaceholder API’s posts endpoint.
The JSONPlaceholder site provides a free dummy API for testing, which is used to provide real-world instances of Invoke-RestMethod requests.
Invoke-RestMethod -Uri “https://jsonplaceholder.typicode.com/posts” Invoke-RestMethod -Uri “https://jsonplaceholder.typicode.com/posts”
JSONPlaceholder API posts endpoint partial output.
The data sent by the REST API https://jsonplaceholder.typicode.com/posts is not in beautiful PowerShell objects, as seen above. Instead, it returns JSON data. The JSON was automatically transformed to PowerShell objects by Invoke-RestMethod.
PowerShell transformed the result to the PSCustomObject type by inspecting a single item in the PowerShell array and using the GetType() function on it, as shown below.
ArrayLists and Arrays in PowerShell Can Help You Write Better Scripts
# Store the API GET response in a variable ($Posts). $Posts = Invoke-RestMethod -Uri “https://jsonplaceholder.typicode.com/posts” Invoke-RestMethod -Uri “https://jsonplaceholder.typicode.com/posts” # Run the GetType() method against the first item in the array, identified by its index of 0. $Posts[0].GetType()
The automated translation of the JSON answer to PowerShell’s PSCustomObject type is seen in the output.
Using an API to authenticate yourself
You used the GET technique to query a public REST API in the previous section. There was no need for authentication using the API. However, you must often authenticate to a REST API in some way.
Basic (username/password) and Bearer (token) authentication are two of the most frequent methods to authenticate to a REST API. When submitting a request, use an Authorization HTTP header to distinguish between these two drastically different authentication techniques.
Let’s look at how you can utilize Invoke-RestMethod to deliver HTTP headers to REST endpoints, particularly the Authorization HTTP header.
The Invoke-RestMethod takes care of a lot of the tedious aspects of making HTTP requests. Despite the fact that an HTTP request must include an Authorization header, there are no references to “headers” in this example. The Invoke-RestMethod cmdlet is used to abstract away ideas like these.
Basic Authentication with a Username and Password
Using a username and password to authenticate to a REST API is the simplest method. You must give a PSCredential object with the login and password to the endpoint in order to collect it.
Using the Get-Credential Cmdlet in PowerShell and all things credentials
Create the PSCredential object first, which will include the login and password.
# This will request credentials and save them in a PSCredential object. Get-Credential $Cred = Get-Credential $Cred = Get-Credential $C
Once you’ve created a PSCredential object in a variable, run the program again, but this time include the Authentication and Credential parameters.
When the Authentication option is set to Basic, an authorization HTTP header with the word Basic and a base64 encoded username:password string like Authorization: Basic is sent. ZGVtbzpwQDU1dzByZA==.
The PSCredential you established before is accepted by the Credential argument.
The example below, as well as many others in this article, employs a technique known as PowerShell splatting, which enables you to create arguments in a hashtable and then give them to the command. In the ATA article PowerShell Splatting: What Is It and How Does It Work?, you can learn more about splatting.
# Make a GET request with Basic authentication included. $Params = @ Uri = “https://jsonplaceholder.typicode.com/posts” Authentication = “Basic” Credential = $Cred Authentication = “Basic” Credential = $Cred Authentication = “Basic” @Params Invoke-RestMethod
Using basic authentication, partial output from the JSONPlaceholder API posts endpoint.
For security concerns, Invoke-RestMethod will return an error if you use the Credential or Authentication parameter option with a Uri that does not begin with https://. Use the AllowUnencryptedAuthentication argument at your own risk to alter this default behavior.
Bearer Authentication using an API/OAuth Token
Basic username and password authentication is acceptable, but not exceptional. Credentials are just base64 encoded (not encrypted), which raises security concerns. APIs often use a token authentication scheme or Bearer/OAuth authentication to handle this.
To use an OAuth token to access a REST API, follow these steps:
1. Retrieve your API’s OAuth token. Your API provider will choose how you receive this token.
2. Next, use the ConvertTo-SecureString cmdlet to convert your token string to a secure string, as illustrated below. The token must be a secure string for the Invoke-RestMethod to work.
$Token = “123h1v23yt2egv1e1e1b2ei1ube2iu12be” | ConvertTo-SecureString -AsPlainText -Force $Token = “123h1v23yt2egv1e1e1b2ei1ube2iu12be”
3. Finally, use the Invoke-RestMethod cmdlet to specify and supply the Uri, Authentication type, and Token. The token will be added to the Authorization HTTP header by Invoke-RestMethod, which will subsequently call the URI specified.
OAuth is an alias for Bearer in the Authentication parameter argument. Both of these parameter values may be used interchangeably.
# Make a GET request with bearer authentication included. $Params = @ Uri = “https://jsonplaceholder.typicode.com/posts” Authentication = “Bearer” Token = $Token Authentication = “Bearer” Token = $Token Authentication = “Bearer” Token = $Token Authentication = “Bearer” Token = $Token Authentication = “Bearer” To @Params Invoke-RestMethod
Using bearer token authentication, partial output from JSONPlaceholder API publishes endpoint.
Using Query Parameters to Retrieve Data
A GET request to a REST API is usually more complicated than a basic, general request to an endpoint. Instead, you must supply parameters to the API to define precisely what you want; you must pass HTTP query parameters.
There are two ways to transmit query parameters with Invoke-RestMethod. You may attach the arguments to the URI directly, as seen below, which sends a userId of 1 and an id of 8 to the URI.
https://jsonplaceholder.typicode.com/posts?userId=1&id=8
You may also use the Body parameter as a hashtable to specify the parameters in the HTTP body. Let’s look at how to use the Body parameter to deliver arguments to an endpoint.
Assemble a hashtable using the query parameter key/value pairs as shown below.
$Body = @ userId = 1 id = 8 $Body = @ userId = 1 id = 8 $Body = @ userId = 1 id
Finally, as seen below, provide the $Body variable to the Body argument.
You may use the value GET to define the Method argument, or you can leave it blank or use Invoke-RestMethod to default to the value.
$Params = @ Method = “Get” Uri = “https://jsonplaceholder.typicode.com/posts” Body = $Body Invoke-RestMethod @Params @Params @Params @Params @Params @Params @Params @Params @Params @Params @Params @Params @Params @Params @Params @Params @Par
The endpoint now only returns the post item you’re searching for, as you can see below.
Using Invoke-RestMethod to query API using HTTP query parameters
Using the POST HTTP Method to Send Data to an API
You were requesting data from a REST API or making HTTP GET queries in the previous cases. You were reading the data it returned, but with many REST APIs, reading is just half the story. To interact with a service, REST APIs must provide a complete CRUD model.
You won’t use a GET HTTP request to make modifications to a service that provides an API; instead, you’ll use a “writable” request like POST.
When utilizing any “writable” HTTP method like PUT or PATCH, you’ll often need to send an HTTP body with your requests.
Using a POST Request to Send JSON Data
Let’s generate a new post item instead of merely reading them using the prior REST API endpoint.
Create a hashtable with all of the properties for the posts API endpoint first. The tutorial’s particular endpoint enables you to create a new post item with a title, body, and userId, as seen below.
$Body = @ title = “foo” body = “bar” $Body = @ title = “foo” body = “bar” userId = 1 userId = 1 userId = 1 userId = 1 user
2. Next, transform the hashtable in the $Body variable to a JSON string and save it in the $JsonBody variable.
Endpoints of the REST protocol You don’t know what a PowerShell hashtable is, and you need to translate it to a language that the REST API can comprehend. It’s not necessary to create a hashtable initially. If you wanted to, you could input the JSON directly and skip this step.
$Body | ConvertTo-Json $JsonBody = $Body
3. Finally, use Invoke-RestMethod with the appropriate arguments. You’ll see that the Method parameter must now be set to Post in the example below. Invoke-RestMethod defaults to make a GET request if the Method option is not specified.
Many REST APIs also need you to give the ContentType, which specifies the HTTP Content-Type header in which the Body is stored. You must use application/json in this case.
Unless otherwise provided, the ContentType for all POST requests will be set to application/x-www-form-urlencoded. @ $Params $Params $Params $Params $Par Body = $JsonBody ContentType = “application/json” Method = “Post” Uri = “https://jsonplaceholder.typicode.com/posts” @Params Invoke-RestMethod
The API produces a post item along with an id for the new post, as seen below.
Using Invoke-RestMethod to send a JSON POST
Using Invoke-RestMethod to Send Form Data
You may be required to send data using the multipart/form-data HTTP content type for certain REST API calls. It’s a little simpler to submit a different content type with Invoke-RestMethod than it is with JSON. The Form parameter is now available in PowerShell 6.1.0.
The Form parameter makes it easy to add multipart/form-data objects to a request without having to utilize the.NET Framework. Directly using the Net.Http.MultipartFormDataContent class.
To use Invoke-RestMethod to deliver form data, first establish a hashtable with each item like before.
$Form = @ title = “foo” body = “bar” userId = 1 userId = 1 userId = 1 userId = 1 userId = 1 userId = 1 userId = 1 userId = 1
You should use the Form parameter instead of the Body parameter. Invoke-RestMethod will also disregard the ContentType argument if you try to supply both the ContentType and the Form parameters at the same time.
Finally, as illustrated below, send the hashtable to the Form argument.
@ $Params $Params $Params $Params $Par “https://jsonplaceholder.typicode.com/posts” Uri = “https://jsonplaceholder.typicode.com/posts” Form = $Form @Params Invoke-RestMethod
Using the Invoke-RestMethod cmdlet to submit a Form Content type
Relationship Links to Follow
APIs often deliver “pages” of data rather than large datasets all at once. The GitHub Problems API, for example, provides 30 issues per page by default. Relation links, which are included in certain API responses to aid browse the dataset, are links to the next (or previous, final, etc.) page of data.
The HTTP response headers must be examined to detect related links sent by an API. The ResponseHeadersVariable argument is one simple method to do this. This argument creates a variable and saves the headers in a hashtable automatically.
Let’s look at the problems in the PowerShell GitHub repo as an example.
1. Make a GET call to the problems endpoint of the PowerShell GitHub project, as illustrated below. To construct a variable, be sure to utilize the ResponseHeadersVariable. The $Headers variable is used in the example below.
# Make a GET call to the GitHub problems API for the PowerShell project repo, then save the return headers in a variable ($Headers). -Uri “https://api.github.com/repos/powershell/powershell/issues” -ResponseHeadersVariable “Headers” Invoke-RestMethod -Uri “https://api.github.com/repos/powershell/powershell/issues” -ResponseHeadersVariable “Headers” # To the terminal, print the $Headers variable. $Headers
The hashtable within the $Headers variable contains a key named Links, as seen below. This key holds the answer’s related connections, indicating that the data set is larger than simply this one response.
Request headers for the GitHub issues API, displaying related connections.
2. Next, use the FollowRelLink argument to follow the relation connections. This option scans each of the related links and sends a GET request to each of them automatically.
The code line below will follow each related connection up to three times. The Invoke-RestMethod cmdlet will stop inquiring for problems when it reaches 90 (30 items per request) in this case.
@ Uri = “https://api.github.com/repos/powershell/powershell/issues” $Params = @ Uri = “https://api.github.com/repos/powershell/powershell/issues” MaximumFollowRelLink = 3 FollowRelLink = $true @Params Invoke-RestMethod
Invoke-RestMethod delivers an array of objects when the FollowRelLink argument is used (Object[]). Each item in the array represents the answer from one of the related connections, which may be a separate array of objects!
Use the FollowRelLink argument to get a partial response from a call to the GitHub problems API.
3. Rerun the same example, but this time look at the original query’s returned results. There will only be three “pages” as indicated by the count of three. However, you’ll see that the first page of results ($Results[0]) has 30 items.
@ Uri = “https://api.github.com/repos/powershell/powershell/issues” $Params = @ Uri = “https://api.github.com/repos/powershell/powershell/issues” MaximumFollowRelLink = 3 FollowRelLink = $true # In the $Results variable, save the three pages of results. @Params $Results = Invoke-RestMethod # Make sure $Results has three items (pages of issues from the GitHub issues API). $Results.Count # Make sure the first item in the $Results array contains the first page of each of the thirty issues. $Results[0].Count
The nested arrays provided by the FollowRelLink option are shown in the output.
4. Finally, use a foreach loop to go through each item in the $Results variable. You’ll see below that you’ll need to use a foreach loop to traverse through each page. Then, for each page, use a nested loop to iterate through all of the elements on that page.
Back to the Basics with PowerShell’s ForEach Loop
# This might be different depending on the data structure of the API you are using. # 1) $Results.ForEach({}) – this loops through each page in the $Results array. # 2) $_.ForEach({}) – this loops through each item in the current page. # 3) $_ – this simply returns each item to the pipeline. $AllResults = @( $Results.ForEach({ $_.ForEach({ $_ }) }) ) # Check that the $AllResults variable contains all ninety items. $AllResults.Count
In a single array ($AllResults), the output shows all ninety GitHub problems.
Keeping Track of Session Data
When dealing with APIs, it’s common to save data from prior requests, such as headers, credentials, proxy information, and cookies, to reuse in later queries. A session is where all of this data is saved.
By saving the session using the SessionVariable argument and subsequently referencing it with the WebSession parameter, the Invoke-RestMethod may take use of sessions.
To illustrate, utilize the SessionVariable argument when using the posts endpoint, as seen below. Invoke-RestMethod will generate a variable named MySession in this case.
The session object isn’t a permanent connection, so keep that in mind. A session is nothing more than an object that stores information about the request.
# Invoke the request storing the session as MySession. # The SessionVariable value shouldn’t include a dollar sign ($). Invoke-RestMethod -Uri “https://jsonplaceholder.typicode.com/posts” Invoke-RestMethod -Uri “https://jsonplaceholder.typicode.com/posts” -SessionVariable “MySession” # Print the session object to the console. $MySession
The session object attributes are shown in the output.
Now, run Invoke-RestMethod with the WebSession option to reuse the session information. As you can see in the following example, all prior session data are given through the $MySession variable in the new request.
# Invoke the request using the session information stored in the $MySession variable. Invoke-RestMethod -Uri “https://jsonplaceholder.typicode.com/posts” Invoke-RestMethod -Uri “https://jsonplaceholder.typicode.com/posts” -WebSession $MySession
A portion of the output demonstrating the reuse of a previously saved session ($MySession).
Session Values That Take Priority
A session is a collection of data about a request. You can override the session if you wish to reuse it but alter a value.
You could want to re-use a previously established session, but this time login using a username and password. Let’s take a look at the current scenario first.
The Credentials attribute of the $MySession object has no value, as you can see below. However, even though the credential was not in the session, the REST endpoint gets it after running Invoke-RestMethod again with the Credential option.
# To show that the Credentials # field is empty, print the $MySession variable to the console. $MySession # Specify the Credential argument to override the session value. # In this case, you’ll be asked to enter your login and password. WebSession = $MySession Credential = (Get-Credential) $Params = @ Uri = “https://jsonplaceholder.typicode.com/posts” @Params Invoke-RestMethod
The parameter name is Credential, whereas the property name in the stored session is Credential. It is not usually the case that the names are identical.
Specifying the Credential option overrides the Credentials value in the session variable ($MySession).
Creating a File with the Response Body
It may be required to store the answer to a request to a file at times. Use the OutFile argument to do this.
Use the OutFile option and supply a file location to query the tutorial’s testing endpoint again using Invoke-RestMethod.
Invoke-RestMethod requests the endpoint, returns the response in JSON format, and stores the raw JSON into the.my-posts.json file, as seen below.
You may also use the PassThru option to save a file with the answer and return it to the console at the same time.
# Save post items to my-posts.json in the current directory. Invoke-RestMethod -Uri “https://jsonplaceholder.typicode.com/posts” Invoke-RestMethod -Uri “https://jsonplaceholder.typicode.com/posts” -OutFile “my-posts.json” # Print the contents of the JSON file to the console. # “.” in this command refers to the current working directory in your terminal session. Get-Content -Path “.my-posts.json”
The contents of my-posts are only partially output. json.
After you’ve stored the answer as JSON in a file, you may parse it for data as needed. A nice example of locating a post with a given ID can be seen below.
# Save the response to “my-posts.json” and also in the $Posts variable using PassThru. $Posts = Invoke-RestMethod -Uri “https://jsonplaceholder.typicode.com/posts” Invoke-RestMethod -Uri “https://jsonplaceholder.typicode.com/posts” -OutFile “my-posts.json” -PassThru # Filter posts with 1 as the userId into a new variable ($User1Posts). $User1Posts = $Posts.Where({$_.userId -eq 1}) # Import all posts from the “my-posts.json” file and store them in the $AllUserPosts variable. $AllUserPosts = Get-Content -Path “.my-posts.json” | ConvertFrom-Json # Print the count of both variables to the console to demonstrate that they are different. $User1Posts.Count $AllUserPosts.Count
Output demonstrating how to use PassThru to save results in both a variable and a file inside the same command.
When it comes to SSL and certificates, there are a few things to keep in mind.
You’ve solely worked with HTTP throughout this lesson. There hasn’t been any mention of HTTPS or SSL. But it doesn’t rule out the possibility of using Invoke-RestMethod with SSL. In fact, it can handle almost any task you throw at it.
Validation of Certificates is skipped.
By default, Invoke-RestMethod verifies the certificate of any SSL site to confirm that it is not expired, revoked, or that the trust chain is intact. Although this is a security feature that you should keep enabled, there are instances when you need to deactivate it, such as during testing.
Creating Certificates using PowerShell: New-SelfSignedCertificate
Use the SkipCertificateCheck option to bypass certificate validation. This argument disables all certificate checking that is normally performed by Invoke-RestMethod.
Specifying a Request’s Client Certificate
Use the Certificate argument of Invoke-RestMethod to provide a client certificate for a specific request. This argument accepts an X509Certificate object as its value, which you may get from the Cert: PSDrive using the Get-PfxCertificate or Get-ChildItem commands.
The following command, for example, makes a call to the JSONPlaceholder APIs posts endpoint using a certificate from the Cert: drive.
# Change location into your personal certificate store. Set-Location “Cert:CurrentUserMy” # Store the certificate with the thumbprint DDE2EC6DBFF56EE9C375A6073C97188ABAA4F5E4 in a variable ($Cert). $Cert = Get-ChildItem | Where-Object {$_.Thumbprint -eq “DDE2EC6DBFF56EE9C375A6073C97188ABAA4F5E4”} # Invoke the command using the client certificate. Invoke-RestMethod -Uri “https://jsonplaceholder.typicode.com/posts” Invoke-RestMethod -Uri “https://jsonplaceholder.typicode.com/posts” -Certificate $Cert
When performing a GET request, use a client certificate.
SSL/TLS Protocol Restrictions
All SSL/TLS protocols supported by your system are enabled by default. Use the SslProtocol argument if you need to limit a request to a certain protocol version(s).
You may call a URI with a version of TLS from v1, 1.1, 1.2, and 1.3 as an array using the SslProtocol.
# Restrict the request to only allow SSL/TLS 1.2 and 1.3 protocol versions. Invoke-RestMethod -Uri “https://jsonplaceholder.typicode.com/posts” Invoke-RestMethod -Uri “https://jsonplaceholder.typicode.com/posts” -SslProtocol @(“Tls12”, “Tls13”)
Tls or Tls12 may not be available on non-Windows systems. Tls13 support isn’t accessible on all operating systems, therefore it’ll have to be checked on a case-by-case basis. Tls13 is only accessible in PowerShell 7.1 and later versions.
Other Interesting Characteristics
Let’s finish off this lesson with a few important parameters that don’t necessary need an instruction section.
Making Use of a Proxy Server
Proxy servers are often used in corporate organizations to regulate internet access. Use the Proxy argument to compel Invoke-RestMethod to proxy its request via a proxy.
If you need to authenticate to the proxy, either provide a PSCredential object to the ProxyCredential argument or use the ProxyUseDefaultCredentials switch option to use the credentials of the currently logged-on user.
# Invoke request using proxy server <http://10.0.10.1:8080> and the current user’s credentials. Invoke-RestMethod -Uri “https://jsonplaceholder.typicode.com/posts” Invoke-RestMethod -Uri “https://jsonplaceholder.typicode.com/posts” -Proxy “http://10.0.10.1:8080” -ProxyUseDefaultCredentials
Checks and Validation are being skipped.
You may be exposed to security concerns if you use these settings. You have been forewarned.
The Invoke-RestMethod cmdlet performs a variety of tests behind the scenes. You may deactivate these tests with a few options if you want to for whatever reason.
- SkipHeaderValidation — Turns off validation for the ContentType, Headers, and UserAgent parameters’ values.
- Any errors will be ignored if you use SkipHttpErrorCheck. Before processing proceeds, the error will be sent to the pipeline.
- When using SkipHttpErrorCheck, you may need to examine the HTTP response status code to determine whether the message is a success or failure. For this reason, the StatusCodeVariable option will give the status code integer value to a variable.
Keep Alive is disabled.
TCP Keep Alive is a useful network function that enables you to keep a connection to a distant server alive (if the server supports it). Keep Alive is not used by default in Invoke-RestMethod.
Set the DisableKeepAlive argument to $false if you want to utilize Keep Alive to possibly reduce the remote server’s CPU and memory use.
Invoke-RestMethod -Uri “https://jsonplaceholder.typicode.com/posts” -Uri “https://jsonplaceholder.typicode.com/posts” -DisableKeepAlive $false Invoke-RestMethod
Changing the Type of Encoding
When Invoke-RestMethod delivers a request to a remote endpoint, it uses a transfer-encoding header to encode the request. By default, Invoke-RestMethod and the server negotiate the encoding method, but you may use the TransferEncoding argument to specify an encoding type manually.
If you want to change the encoding type, use the following commands:
- Chunked
- Compress
- Deflate
- GZip
- Identity
Conclusion
You’ve seen how Invoke-RestMethod makes communicating with REST APIs considerably simpler than normal web requests in this lesson. You’ve studied parameters for authentication, sending data in the body of a request, keeping session state, downloading files, and more.
What REST API would you test this handy cmdlet on now that you’re up to speed on Invoke-RestMethod and dealing with REST APIs?
.ForEach( $ ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) # Make sure the $AllResults variable has all ninety entries in it. $AllResults.Count
In a single array ($AllResults), the output shows all ninety GitHub problems.
Keeping Track of Session Data
When dealing with APIs, it’s common to save data from prior requests, such as headers, credentials, proxy information, and cookies, to reuse in later queries. A session is where all of this data is saved.
By saving the session using the SessionVariable argument and subsequently referencing it with the WebSession parameter, the Invoke-RestMethod may take use of sessions.
To illustrate, utilize the SessionVariable argument when using the posts endpoint, as seen below. Invoke-RestMethod will generate a variable named MySession in this case.
The session object isn’t a permanent connection, so keep that in mind. A session is nothing more than an object that stores information about the request.
# Invoke the request storing the session as MySession. # The SessionVariable value shouldn’t include a dollar sign ($). Invoke-RestMethod -Uri “https://jsonplaceholder.typicode.com/posts” Invoke-RestMethod -Uri “https://jsonplaceholder.typicode.com/posts” -SessionVariable “MySession” # Print the session object to the console. $MySession
The session object attributes are shown in the output.
Now, run Invoke-RestMethod with the WebSession option to reuse the session information. As you can see in the following example, all prior session data are given through the $MySession variable in the new request.
# Invoke the request using the session information stored in the $MySession variable. Invoke-RestMethod -Uri “https://jsonplaceholder.typicode.com/posts” Invoke-RestMethod -Uri “https://jsonplaceholder.typicode.com/posts” -WebSession $MySession
A portion of the output demonstrating the reuse of a previously saved session ($MySession).
Session Values That Take Priority
A session is a collection of data about a request. You can override the session if you wish to reuse it but alter a value.
You could want to re-use a previously established session, but this time login using a username and password. Let’s take a look at the current scenario first.
The Credentials attribute of the $MySession object has no value, as you can see below. However, even though the credential was not in the session, the REST endpoint gets it after running Invoke-RestMethod again with the Credential option.
# To show that the Credentials # field is empty, print the $MySession variable to the console. $MySession # Specify the Credential argument to override the session value. # In this case, you’ll be asked to enter your login and password. WebSession = $MySession Credential = (Get-Credential) $Params = @ Uri = “https://jsonplaceholder.typicode.com/posts” @Params Invoke-RestMethod
The parameter name is Credential, whereas the property name in the stored session is Credential. It is not usually the case that the names are identical.
Specifying the Credential option overrides the Credentials value in the session variable ($MySession).
Creating a File with the Response Body
It may be required to store the answer to a request to a file at times. Use the OutFile argument to do this.
Use the OutFile option and supply a file location to query the tutorial’s testing endpoint again using Invoke-RestMethod.
Invoke-RestMethod requests the endpoint, returns the response in JSON format, and stores the raw JSON into the.my-posts.json file, as seen below.
You may also use the PassThru option to save a file with the answer and return it to the console at the same time.
# Save post items to my-posts.json in the current directory. Invoke-RestMethod -Uri “https://jsonplaceholder.typicode.com/posts” Invoke-RestMethod -Uri “https://jsonplaceholder.typicode.com/posts” -OutFile “my-posts.json” # Print the contents of the JSON file to the console. # “.” in this command refers to the current working directory in your terminal session. Get-Content -Path “.my-posts.json”
The contents of my-posts are only partially output. json.
After you’ve stored the answer as JSON in a file, you may parse it for data as needed. A nice example of locating a post with a given ID can be seen below.
# Save the response to “my-posts.json” and also in the $Posts variable using PassThru. $Posts = Invoke-RestMethod -Uri “https://jsonplaceholder.typicode.com/posts” Invoke-RestMethod -Uri “https://jsonplaceholder.typicode.com/posts” -OutFile “my-posts.json” -PassThru # Filter posts with 1 as the userId into a new variable ($User1Posts). $User1Posts = $Posts.Where({$_.userId -eq 1}) # Import all posts from the “my-posts.json” file and store them in the $AllUserPosts variable. $AllUserPosts = Get-Content -Path “.my-posts.json” | ConvertFrom-Json # Print the count of both variables to the console to demonstrate that they are different. $User1Posts.Count $AllUserPosts.Count
Output demonstrating how to use PassThru to save results in both a variable and a file inside the same command.
When it comes to SSL and certificates, there are a few things to keep in mind.
You’ve solely worked with HTTP throughout this lesson. There hasn’t been any mention of HTTPS or SSL. But it doesn’t rule out the possibility of using Invoke-RestMethod with SSL. In fact, it can handle almost any task you throw at it.
Validation of Certificates is skipped.
By default, Invoke-RestMethod verifies the certificate of any SSL site to confirm that it is not expired, revoked, or that the trust chain is intact. Although this is a security feature that you should keep enabled, there are instances when you need to deactivate it, such as during testing.
Creating Certificates using PowerShell: New-SelfSignedCertificate
Use the SkipCertificateCheck option to bypass certificate validation. This argument disables all certificate checking that is normally performed by Invoke-RestMethod.
Specifying a Request’s Client Certificate
Use the Certificate argument of Invoke-RestMethod to provide a client certificate for a specific request. This argument accepts an X509Certificate object as its value, which you may get from the Cert: PSDrive using the Get-PfxCertificate or Get-ChildItem commands.
The following command, for example, makes a call to the JSONPlaceholder APIs posts endpoint using a certificate from the Cert: drive.
# Change location into your personal certificate store. Set-Location “Cert:CurrentUserMy” # Store the certificate with the thumbprint DDE2EC6DBFF56EE9C375A6073C97188ABAA4F5E4 in a variable ($Cert). $Cert = Get-ChildItem | Where-Object {$_.Thumbprint -eq “DDE2EC6DBFF56EE9C375A6073C97188ABAA4F5E4”} # Invoke the command using the client certificate. Invoke-RestMethod -Uri “https://jsonplaceholder.typicode.com/posts” Invoke-RestMethod -Uri “https://jsonplaceholder.typicode.com/posts” -Certificate $Cert
When performing a GET request, use a client certificate.
SSL/TLS Protocol Restrictions
All SSL/TLS protocols supported by your system are enabled by default. Use the SslProtocol argument if you need to limit a request to a certain protocol version(s).
You may call a URI with a version of TLS from v1, 1.1, 1.2, and 1.3 as an array using the SslProtocol.
# Restrict the request to only allow SSL/TLS 1.2 and 1.3 protocol versions. Invoke-RestMethod -Uri “https://jsonplaceholder.typicode.com/posts” Invoke-RestMethod -Uri “https://jsonplaceholder.typicode.com/posts” -SslProtocol @(“Tls12”, “Tls13”)
Tls or Tls12 may not be available on non-Windows systems. Tls13 support isn’t accessible on all operating systems, therefore it’ll have to be checked on a case-by-case basis. Tls13 is only accessible in PowerShell 7.1 and later versions.
Other Interesting Characteristics
Let’s finish off this lesson with a few important parameters that don’t necessary need an instruction section.
Making Use of a Proxy Server
Proxy servers are often used in corporate organizations to regulate internet access. Use the Proxy argument to compel Invoke-RestMethod to proxy its request via a proxy.
If you need to authenticate to the proxy, either provide a PSCredential object to the ProxyCredential argument or use the ProxyUseDefaultCredentials switch option to use the credentials of the currently logged-on user.
# Invoke request using proxy server <http://10.0.10.1:8080> and the current user’s credentials. Invoke-RestMethod -Uri “https://jsonplaceholder.typicode.com/posts” Invoke-RestMethod -Uri “https://jsonplaceholder.typicode.com/posts” -Proxy “http://10.0.10.1:8080” -ProxyUseDefaultCredentials
Checks and Validation are being skipped.
You may be exposed to security concerns if you use these settings. You have been forewarned.
The Invoke-RestMethod cmdlet performs a variety of tests behind the scenes. You may deactivate these tests with a few options if you want to for whatever reason.
- SkipHeaderValidation — Turns off validation for the ContentType, Headers, and UserAgent parameters’ values.
- Any errors will be ignored if you use SkipHttpErrorCheck. Before processing proceeds, the error will be sent to the pipeline.
- When using SkipHttpErrorCheck, you may need to examine the HTTP response status code to determine whether the message is a success or failure. For this reason, the StatusCodeVariable option will give the status code integer value to a variable.
Keep Alive is disabled.
TCP Keep Alive is a useful network function that enables you to keep a connection to a distant server alive (if the server supports it). Keep Alive is not used by default in Invoke-RestMethod.
Set the DisableKeepAlive argument to $false if you want to utilize Keep Alive to possibly reduce the remote server’s CPU and memory use.
Invoke-RestMethod -Uri “https://jsonplaceholder.typicode.com/posts” -Uri “https://jsonplaceholder.typicode.com/posts” -DisableKeepAlive $false Invoke-RestMethod
Changing the Type of Encoding
When Invoke-RestMethod delivers a request to a remote endpoint, it uses a transfer-encoding header to encode the request. By default, Invoke-RestMethod and the server negotiate the encoding method, but you may use the TransferEncoding argument to specify an encoding type manually.
If you want to change the encoding type, use the following commands:
- Chunked
- Compress
- Deflate
- GZip
- Identity
Conclusion
You’ve seen how Invoke-RestMethod makes communicating with REST APIs considerably simpler than normal web requests in this lesson. You’ve studied parameters for authentication, sending data in the body of a request, keeping session state, downloading files, and more.
What REST API would you test this handy cmdlet on now that you’re up to speed on Invoke-RestMethod and dealing with REST APIs?
The “powershell rest api oauth2 example” is a tutorial that shows how to work with REST APIs and PowerShell’s Invoke.
Related Tags
- invoke-restmethod : a parameter cannot be found that matches parameter name ‘authentication’.
- powershell script to call rest api get
- invoke rest method powershell
- powershell rest api basic authentication
- powershell api call json