Unable to Provision Msa Id Automatically Please Pass Them in as Parameters and Try Again
Do y'all often access awarding programming interfaces (APIs) using PowerShell? Mayhap you want to only don't know where to start? Whether you're a PowerShell pro or just starting, this tutorial has yous covered with a congenital-in PowerShell cmdlet that interacts with APIs chosen Invoke-RestMethod.
In this article, you'll learn many different means to work with representational state transfer (Residuum) APIs from using GET and POST requests, covering authentication, how to download files, and more!
Invoke-RestMethod in a Nutshell
When yous need to retrieve or send data to a Remainder API, you demand a client. In the PowerShell globe, that client is the Invoke-RestMethod cmdlet. This cmdlet sends HTTP requests using various HTTP methods to REST API endpoints.
HTTP methods so instruct REST APIs to carry out various actions to be performed on a resource.
The official HTTP methods are Get, HEAD, POST, PUT, DELETE, CONNECT, OPTIONS, TRACE, and PATCH, although some APIs may implement custom methods.
The Invoke-RestMethod cmdlet supports all HTTP methods, including authentication, sending different HTTP headers, HTTP bodies, and also automatically translates JSON and XML responses to PowerShell objects. The Invoke-RestMethod cmdlet is the PowerShell cmdlet to collaborate with Residual APIs!
Prerequisites
If you lot'd like to follow along with the many demos in this tutorial, exist sure that you have:
- PowerShell seven.0 or afterward installed. This tutorial uses a Windows x motorcar and PowerShell 7.1.
Without further ado, open your PowerShell console and/or code editor and permit'due south become started!
Retrieving Information via a Simple GET asking
Allow'southward commencement things off with the simplest case out in that location; querying a Residual API with a Get asking. Invoke-RestMethod can practice a lot, simply y'all need to empathize the basics starting time.
To send a elementary Go request to a REST API endpoint, you'll only need 1 parameter, Uri. The Uri parameter is what tells Invoke-RestMethod where the endpoint is.
For example, run the command below. This command queries the JSONPlaceholder APIs posts endpoint and returns a list of post resources.
The JSONPlaceholder site offers a free fake API for testing, which is used to demonstrate existent examples of queries with the
Invoke-RestMethodcommand.
Invoke-RestMethod -Uri "https://jsonplaceholder.typicode.com/posts"
When the REST endpoint https://jsonplaceholder.typicode.com/posts returns data, it doesn't return information technology in squeamish PowerShell objects, as you see to a higher place. Instead, it returns data in JSON. Invoke-RestMethod automatically converted the JSON to PowerShell objects for you lot.
You tin see below that PowerShell converted the output to the PSCustomObject type past looking at a single particular in the PowerShell array and running the GetType() method on it.
# Store the API Get response in a variable ($Posts). $Posts = Invoke-RestMethod -Uri "https://jsonplaceholder.typicode.com/posts" # Run the GetType() method against the first item in the array, identified by its alphabetize of 0. $Posts[0].GetType()
Authenticating to an API
In the previous department, you queried a public REST API using the GET method. The API didn't require any authentication. Much of the time, though, you must cosign to a REST API somehow.
Two of the most common ways to cosign to a REST API is using Bones (username/password) or Bearer (token) authentication. To differentiate between these two wildly different authentication schemes requires using an Authorization HTTP header when sending the request.
Let's at present cover how y'all can utilise Invoke-RestMethod to send HTTP headers (peculiarly the Authorization HTTP header) to Residue endpoints.
The
Invoke-RestMethodabstracts away a lot of the tedium to sending HTTP requests. Fifty-fifty though you must provide an Dominance header in an HTTP request, you'll see no references to "headers" in this example. Abstracting away concepts like this is common with theInvoke-RestMethodcmdlet.
Using a Username and Password with Basic Authentication
The simplest manner to authenticate to a REST endpoint is using a username and password. To capture that username and password, you lot must pass a PSCredential object to the endpoint that contains the username and password.
First, create the PSCredential object containing the username and countersign.
# This will prompt for credentials and shop them in a PSCredential object. $Cred = Go-Credential Once you have a PSCredential object stored in a variable, laissez passer the required URI to the command only this time add together the Authentication and Credential parameter.
Setting the Authentication parameter sends an authorization HTTP header containing the word Basic, followed past a base64 encoded username:password string like Authorization: Basic ZGVtbzpwQDU1dzByZA==.
The Credential parameter accepts the PSCredential y'all created earlier.
The beneath example and many more in this tutorial employ a concept called PowerShell splatting that allows you lot to define parameters in a hashtable and so laissez passer to the control. Learn more well-nigh splatting in the ATA mail service PowerShell Splatting: What is it and how does it piece of work?
# Send a GET asking including Bones authentication. $Params = @{ Uri = "https://jsonplaceholder.typicode.com/posts" Authentication = "Basic" Credential = $Cred } Invoke-RestMethod @Params
If you lot use the
CredentialorAuthenticationparameter option with aUrithat does not begin with https://,Invoke-RestMethodwill return an error for security reasons. The override this default behavior, employ theAllowUnencryptedAuthenticationparameter at your own take a chance.
Using an API/OAuth Token with Bearer Authentication
Basic username and password authentication are OK, but it'southward not groovy. Credentials are simply encoded equally base64 (not encrypted) which opens up security issues. To address this, APIs usually implement a token authentication organization or Bearer/OAuth authentication.
To authenticate to a REST API with an OAuth token:
one. Obtain the OAuth token from your API. How this token is obtained will depend on your API provider.
ii. Next, catechumen your token string into a secure string with the ConvertTo-SecureString cmdlet, equally shown below. The Invoke-RestMethod requires the token to be a secure string.
$Token = "123h1v23yt2egv1e1e1b2ei1ube2iu12be" | ConvertTo-SecureString -AsPlainText -Forcefulness 3. Finally, define and pass the Uri, Authentication type, and Token to the Invoke-RestMethod cmdlet. Invoke-RestMethod will and so telephone call the URI provided and add the token to the Authority HTTP header.
The
Authenticationparameter argumentOAuthis an alias forBearer. You lot can utilise both of these parameter values interchangeably.
# Send a Become request including bearer hallmark. $Params = @{ Uri = "https://jsonplaceholder.typicode.com/posts" Authentication = "Bearer" Token = $Token } Invoke-RestMethod @Params
Retrieving Information with Using Query Parameters
Typically, sending a GET request to a Remainder API is more involved than just a simple, generic request to an endpoint. Instead, you demand to pass parameters to specify exactly what you need from the API; you need to pass HTTP query parameters.
To send query parameters with Invoke-RestMethod, y'all accept two options. You tin either direct suspend the parameters to the URI, every bit shown beneath, which passes a userId of ane and an id of 8.
https://jsonplaceholder.typicode.com/posts?userId=ane&id=viii Or, y'all could define the parameters in the HTTP body using the Body parameter as a hashtable. Let's cover how to pass parameters to an endpoint using the Torso parameter.
Create a hashtable containing the query parameter key/value pairs, every bit follows.
$Body = @{ userId = 1 id = viii } Finally, provide the $Body variable to the Trunk parameter, as shown beneath.
You can specify the
Methodparameter using a value ofGETor exclude theMethodparameter orInvoke-RestMethodto default to the value.
$Params = @{ Method = "Get" Uri = "https://jsonplaceholder.typicode.com/posts" Body = $Body } Invoke-RestMethod @Params You can now run across below that the endpoint only returns the post item y'all're looking for.
Sending Data to an API with the POST HTTP Method
In the previous examples, y'all were querying information from a REST API or using HTTP GET requests. You were reading the data it sent back, but reading is only half the story with many Residuum APIs. REST APIs must back up a full Grime model so you can interact with the service.
When yous need to make changes to a service providing an API, you won't employ a Become HTTP request; you'll utilise a "writable" asking similar Mail service.
You'll too typically need to pass an HTTP torso with requests when using any "writable" HTTP method like PUT or PATCH.
Sending JSON Data in a POST Request
Using the previous REST API endpoint, let's now create a new mail service item rather than just reading them.
i. First, create a hashtable including all of the attributes for the posts API endpoint. Yous'll see below that the tutorial'south specific endpoint allows you to create a new postal service item with a title, body and userId.
$Body = @{ title = "foo" body = "bar" userId = 1 } 2. Next, convert the hashtable represented in the $Torso variable to a JSON string storing information technology in a new variable $JsonBody.
REST endpoints don't know what a PowerShell hashtable is, and yous must catechumen the object into a linguistic communication that the REST API understands. Creating a hashtable first is optional. Yous could type up the JSON straight and skip this step if you lot wanted to.
$JsonBody = $Trunk | ConvertTo-Json 3. Finally, craft the required parameters and run Invoke-RestMethod. Notice below that you must now use the Method parameter with a value of Mail. Without using the Method parameter, Invoke-RestMethod defaults to sending a GET request.
Likewise, many Balance APIs require you to specify the ContentType indicating the HTTP Content-Type header the Body is stored in. In this instance, y'all must employ application/json.
# The ContentType will automatically be gear up to awarding/x-world wide web-grade-urlencoded for # all Mail requests, unless specified otherwise. $Params = @{ Method = "Post" Uri = "https://jsonplaceholder.typicode.com/posts" Body = $JsonBody ContentType = "application/json" } Invoke-RestMethod @Params Notice beneath that the API returns a post item along with an id for that new postal service.
Sending Class Data with Invoke-RestMethod
Some Balance API endpoints may require you to submit information via the multipart/form-data HTTP content blazon. To send a different content blazon with Invoke-RestMethod is a fleck easier than using JSON. Since PowerShell 6.1.0, you can now utilize the Form parameter.
The Form parameter provides a convenient way to add multipart/form-information objects to a request without the demand to use the .Cyberspace System.Net.Http.MultipartFormDataContent class directly.
To send form data with Invoke-RestMethod, first, create a hashtable with each item as before.
$Form = @{ title = "foo" body = "bar" userId = i } Discover using the
Formparameter; y'all don't need to employ theBodyparameter. Besides, if you attempt to specify theContentTypeand theGradeparameter together,Invoke-RestMethodvolition ignore theContentTypeparameter.
Finally, just pass the hashtable to the Form parameter, as shown below.
$Params = @{ Method = "Mail" Uri = "https://jsonplaceholder.typicode.com/posts" Class = $Form } Invoke-RestMethod @Params
Following Relation Links
Rather than returning massive datasets in i go, APIs ofttimes return "pages" of data. For instance, the GitHub Bug API returns 30 issues per page by default. Some APIs include links to the adjacent (or previous, last, etc.) folio of data the response to help navigate the dataset known as relation links.
To notice relation links an API returns, you must inspect the HTTP response headers. I easy way to do that is to apply the ResponseHeadersVariable parameter. This parameter automatically creates a variable and stores the headers in a hashtable.
Let's use the PowerShell GitHub repo'due south issues as an example.
1. Make a Go asking to the PowerShell GitHub repo's issues endpoint, as shown below. Be sure to employ the ResponseHeadersVariable to create a variable. The below example uses the $Headers variable.
# Event Become asking to GitHub issues API for the PowerShell projection repo and shop # the response headers in a variable ($Headers). Invoke-RestMethod -Uri "https://api.github.com/repos/powershell/powershell/problems" -ResponseHeadersVariable "Headers" # Print the $Headers variable to the console. $Headers Notice below that the hashtable inside of the $Headers variable has a cardinal called Links. This key contains the relation links for the response that indicates the information set is bigger than merely this one response.
2. Next, follow the relation links using the FollowRelLink parameter. This parameter automatically reads each of the relation links and problems a GET request for each of them.
The below code snippet is following each relation link upwards to three. In this example, the Invoke-RestMethod cmdlet volition stop querying for issues once it hits 90 (30 items per request) using the
$Params = @{ Uri = "https://api.github.com/repos/powershell/powershell/issues" FollowRelLink = $true MaximumFollowRelLink = 3 } Invoke-RestMethod @Params When using the FollowRelLink parameter, Invoke-RestMethod returns an assortment of objects (Object[]). Each detail in the array contains the response from one of the relation links, which could be another array of objects itself!
3. Re-run the previous example merely this time check on the returned results from the initial query. You'll see a count of only three, meaning iii "pages." Simply y'all'll see that the first page of items ($Results[0]) contains 30 items.
$Params = @{ Uri = "https://api.github.com/repos/powershell/powershell/issues" FollowRelLink = $truthful MaximumFollowRelLink = 3 } # Store the 3 pages of results in the $Results variable. $Results = Invoke-RestMethod @Params # Cheque that $Results contains iii items (pages of issues from the GitHub issues API). $Results.Count # Check that the showtime item in the $Results array contains the first folio of thirty issues. $Results[0].Count
iv. Finally, iterate over each item in the $Results variable using a foreach loop. Yous'll see below you'll accept to iterate over each folio with a foreach loop. Then, for each page, iterate over all of the items in that page requiring a nested loop.
# This might be dissimilar depending on the data structure of the API you are using. # one) $Results.ForEach({}) - this loops through each page in the $Results array. # 2) $_.ForEach({}) - this loops through each particular in the current page. # three) $_ - this simply returns each item to the pipeline. $AllResults = @( $Results.ForEach({ $_.ForEach({ $_ }) }) ) # Bank check that the $AllResults variable contains all ninety items. $AllResults.Count
$AllResults).Maintaining Session Information
When working with APIs, it's often useful to store data related to a previous request such as headers, credentials, proxy details, and cookies, to re-utilize in subsequent requests. All of this data is stored in a session.
The Invoke-RestMethod can leverage sessions by storing the session using the SessionVariable parameter and then referencing that session using the WebSession parameter.
To demonstrate, telephone call the posts endpoint again and this fourth dimension utilise the SessionVariable parameter, as shown below. In this instance, Invoke-RestMethod will create a variable called MySession.
Retrieve, the session object isn't a persistent connectedness. A session is simply an object that contains 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" -SessionVariable "MySession" # Print the session object to the console. $MySession
Now, re-utilize the session information by calling Invoke-RestMethod with the WebSession parameter. As yous can run across in the following example, all previous session values are passed via the $MySession variable in the new request.
# Invoke the asking using the session data stored in the $MySession variable. Invoke-RestMethod -Uri "https://jsonplaceholder.typicode.com/posts" -WebSession $MySession
Overriding Session Values
A session contains various information about the request. If you lot desire to re-use the session but change a value, you can override it.
Perhaps, yous'd similar to re-employ the session previously created but now cosign with a username and password. Let's showtime see what the earlier situation looks like.
Discover below that the $MySession object does non contain whatsoever value for the Credentials property. But, afterward invoking Invoke-RestMethod once again using the Credential parameter, the REST endpoint receives the credential even though it wasn't in the session.
# Print the $MySession variable to the console to demonstrate that the Credentials # property is empty. $MySession # Override the session value by specifying the Credential parameter. # In this example you lot will exist prompted for the username and countersign. $Params = @{ Uri = "https://jsonplaceholder.typicode.com/posts" WebSession = $MySession Credential = (Get-Credential) } Invoke-RestMethod @Params The property in the saved session is named
Credentials, but the parameter proper name isCredential. The names volition not e'er match.
Saving the Response Trunk to a File
Sometimes it will be necessary to save the response from a request to a file. To do that, use the OutFile parameter.
Run Invoke-RestMethod over again to query the tutorial's testing endpoint just this time employ the OutFile parameter and provide a file path.
Yous'll run into below that Invoke-RestMethod queries the endpoint, returns the response in JSON format, and then saves the raw JSON into the .\my-posts.json file.
You can as well use the
PassThruparameter to return the response to the console and save a file with the response at one time.
# Save post items to my-posts.json in the current directory. Invoke-RestMethod -Uri "https://jsonplaceholder.typicode.com/posts" -OutFile "my-posts.json" # Impress the contents of the JSON file to the console. # ".\" in this control refers to the electric current working directory in your terminal session. Go-Content -Path ".\my-posts.json"
One time y'all take the response saved as JSON in a file, you can parse it for information as you'd like. Below you'll find a good example of finding a post with a specific ID.
# Save the response to "my-posts.json" and too in the $Posts variable using PassThru. $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 ane}) # 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 # Impress the count of both variables to the console to demonstrate that they are different. $User1Posts.Count $AllUserPosts.Count
Working with SSL and Certificates
Throughout this tutorial, you've only been working with HTTP. HTTPS and SSL oasis't come into the picture. Only that doesn't hateful Invoke-RestMethod won't piece of work with SSL. In fact, information technology can manage just about anything you lot need.
Skipping Certificate Validation
By default, Invoke-RestMethod validates whatsoever SSL site'southward certificate to ensure information technology'south not expired, revoked, or the trust chain is intact. Although this behavior is a security feature you should leave on, in that location are times, similar when testing, yous demand to disable it.
To skip document validation, use the SkipCertificateCheck parameter. This parameter removes all certificate validation Invoke-RestMethod typically runs.
Specifying a Client Document for a Request
If you lot need to specify a client certificate for a detail request, utilise Invoke-RestMethod'due south Certificate parameter. This parameter takes an X509Certificate object as its value which y'all can retrieve using the Become-PfxCertificate command or the Get-ChildItem control from within the Cert: PSDrive.
For example, the following control uses a certificate from the Cert: drive to make a asking to the JSONPlaceholder APIs posts endpoint.
# Change location into your personal document store. Ready-Location "Cert:\CurrentUser\My\" # Store the certificate with the thumbprint DDE2EC6DBFF56EE9C375A6073C97188ABAA4F5E4 in a variable ($Cert). $Cert = Become-ChildItem | Where-Object {$_.Thumbprint -eq "DDE2EC6DBFF56EE9C375A6073C97188ABAA4F5E4"} # Invoke the command using the client certificate. Invoke-RestMethod -Uri "https://jsonplaceholder.typicode.com/posts" -Certificate $Cert
Restricting SSL/TLS Protocols
By default, all SSL/TLS protocols supported by your organization are allowed. But, if you demand to restrict a request to a specific protocol version(s), use the SslProtocol parameter.
Using the SslProtocol, you can specifically call a URI with a version of TLS from v1, one.1, 1.2 and one.3 as an array.
# Restrict the request to only allow SSL/TLS ane.ii and 1.three protocol versions. Invoke-RestMethod -Uri "https://jsonplaceholder.typicode.com/posts" -SslProtocol @("Tls12", "Tls13") On not-Windows platforms, you may not have
TlsorTls12as an selection. Support forTls13is non bachelor on all operating systems and will need to be verified on a per operating arrangement ground.Tls13is only available in PowerShell 7.1+.
Other Interesting Features
To wrap up this tutorial, let'south finish off with some useful parameters simply don't necessarily need an education department.
Using a Proxy Server
Corporate environments ofttimes use proxy servers to manage internet access. To strength Invoke-RestMethod to proxy its request through a proxy, use the Proxy parameter.
If you need to authenticate to the proxy, either supply a PSCredential object to the ProxyCredential parameter or use the switch parameter ProxyUseDefaultCredentials to use the currently logged-on user'south credentials.
# Invoke request using proxy server <http://x.0.x.1:8080> and the current user's credentials. Invoke-RestMethod -Uri "https://jsonplaceholder.typicode.com/posts" -Proxy "http://10.0.10.1:8080" -ProxyUseDefaultCredentials Skipping Checks and Validation
Using these parameters can expose you to potential security risks. You've been warned!
The Invoke-RestMethod cmdlet has many dissimilar checks it does nether the hood. If y'all'd adopt to disable these checks for some reason, you can practise with with a few parameters.
- SkipHeaderValidation – Disable validation for values passed to the
ContentType,Headers, andUserAgentparameters. - SkipHttpErrorCheck – Any errors will be ignored. The error will exist written to the pipeline before processing continues.
- StatusCodeVariable – When using
SkipHttpErrorCheck, you might need to check the HTTP response status code to identify success or failure messages. TheStatusCodeVariableparameter will assign the status code integer value to a variable for this purpose.
Disabling Proceed Alive
TCP Go on Live is a handy network-level feature that allows yous to create a persistent connection to a remote server (if the server supports information technology). By default, Invoke-RestMethod does not utilize Continue Alive.
If you'd like to use Continue Alive, potentially reducing the CPU and memory usage of the remote server, set the DisableKeepAlive parameter to $fake.
Invoke-RestMethod -Uri "https://jsonplaceholder.typicode.com/posts" -DisableKeepAlive $false Irresolute the Encoding Blazon
Whenever Invoke-RestMethod sends a request to a remote endpoint, it encodes the request using a transfer-encoding header. By default, Invoke-RestMethod and the server negotiate this encoding method, but you can explicitly define an encoding type with the TransferEncoding parameter.
If you'd like to change the encoding type, you lot may do using:
- Chunked
- Compress
- Deflate
- GZip
- Identity
Conclusion
In this tutorial, you've learned how Invoke-RestMethod makes interacting with REST APIs much easier than with standard web requests. You've looked at parameters for hallmark, sending data in the body of a request, maintaining session country, downloading files, and much more.
Now that you lot're up to speed on Invoke-RestMethod and working with REST APIs, what REST API will you endeavor this handy cmdlet on?
Source: https://adamtheautomator.com/invoke-restmethod/
Post a Comment for "Unable to Provision Msa Id Automatically Please Pass Them in as Parameters and Try Again"