60

Is there a way to store the return code somewhere when calling Invoke-RestMethod in PowerShell?

My code looks like this:

$url = "http://www.dictionaryapi.com/api/v1/references/collegiate/xml/Adventure?key=MyKeyGoesHere"

$XMLReturned = Invoke-RestMethod -Uri $url -Method Get;

I don't see anywhere in my $XMLReturned variable a return code of 200. Where can I find that return code?

Ansgar Wiechers
  • 193,178
  • 25
  • 254
  • 328
user952342
  • 2,602
  • 7
  • 34
  • 54

6 Answers6

55

You have a few options. Option 1 is found here. It pulls the response code from the results found in the exception.

try {
    Invoke-RestMethod ... your parameters here ... 
} catch {
    # Dig into the exception to get the Response details.
    # Note that value__ is not a typo.
    Write-Host "StatusCode:" $_.Exception.Response.StatusCode.value__ 
    Write-Host "StatusDescription:" $_.Exception.Response.StatusDescription
}

Another option is to use the old invoke-webrequest cmdlet found here.

Code copied from there is:

$resp = try { Invoke-WebRequest ... } catch { $_.Exception.Response }

Those are 2 ways of doing it which you can try.

Community
  • 1
  • 1
Ali Razeghi - AWS
  • 722
  • 1
  • 6
  • 19
  • 18
    The first method requires an exception, so it wouldn't work for the asker's scenario of getting a 200 response. `Invoke-WebRequest` is the way to go; it's not "old"; and it doesn't require `try`/`catch` or an exception. You might want to edit the answer a bit to show that, and to explain that `Invoke-RestMethod` just converts the content from JSON to object automatically, which can be achieved with `iwr` by piping the content to `ConvertFrom-Json`. – briantist Jul 27 '16 at 20:46
  • Thanks will do so shortly. I just meant old as in invoke-restmethod is supposed to replace it at some point, good call on not needing the catch too though! – Ali Razeghi - AWS Jul 27 '16 at 21:33
  • 13
    `Invoke-RestMethod` and `Invoke-WebRequest` were added at the same time; neither is a replacement for the other (if anything `iwr` supersedes `irm` since it's more versatile). `irm` is a shortcut for what you could do with `iwr` and `ConvertFrom-Json`, to just make things a bit quicker. I will upvote your answer if you improve it. – briantist Jul 28 '16 at 13:30
  • It's not clear how this piping to ConvertFrom-Json works. I took the Content (which just looks like a stream of bytes) and piped in to ConvertFrom-Json and got a (you guess it) a stream of bytes. So if this is edited, a little more clarification will be required. – Michael Welch Jun 28 '20 at 22:50
  • 1
    @briantist Invoke-WebRequest for a non-success HTTP message needs try/catch blocks. https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/invoke-webrequest?view=powershell-7.1#example-7--catch-non-success-messages-from-invoke-webrequest – Vahid Farahmandian Jul 17 '21 at 09:40
  • Thank you, sir. I confused myself by hardcoding a 501 status code and forgetting about it. It looked like the request was successful, but the command still failed (while printing the successful response). This helped me debug and find out the trap I set out for myself :) – Tatiana Racheva Aug 29 '23 at 05:27
31

The short answer is: You can't.
You should use Invoke-WebRequest instead.

The two are very similar, the main difference being:

  • Invoke-RestMethod returns the response body only, conveniently pre-parsed.
  • Invoke-WebRequest returns the full response, including response headers and status code, but without parsing the response body.
PS> $response = Invoke-WebRequest -Uri $url -Method Get

PS> $response.StatusCode
200

PS> $response.Content
(…xml as string…)
Grilse
  • 3,491
  • 2
  • 28
  • 35
  • I am using PowerShell to download a JAR file from Artifactory, but the response is empty or nothing, so there is no status code. How I can check if the request was successful? – tarekahf Jan 20 '22 at 17:51
  • `Invoke-WebRequest` was throwing exception on 403, so nothing was assigned to `$response` – Carl Walsh Jun 14 '23 at 23:56
  • 1
    @CarlWalsh Check out the `-SkipHttpErrorCheck` parameter, it changes exactly that behaviour. – Grilse Jun 18 '23 at 08:44
4

Invoke-WebRequest would solve your problem

$response = Invoke-WebRequest -Uri $url -Method Get
if ($response.StatusCode -lt 300){
   Write-Host $response
}

Try catch the call if you want

try {
   $response = Invoke-WebRequest -Uri $url -Method Get
   if ($response.StatusCode -lt 300){
      Write-Host $response
   }
   else {
      Write-Host $response.StatusCode
      Write-Host $response.StatusDescription
   }
}
catch {
   Write-Host $_.Exception.Response.StatusDescription
}
Trung
  • 61
  • 4
4

PowerShell 7 introduced parameter StatusCodeVariable for the Invoke-RestMethod cmdlet. Pass a variable name without the dollar sign ($):

$XMLReturned = Invoke-RestMethod -Uri $url -Method Get -StatusCodeVariable 'statusCode'

# Access status code via $statusCode variable
CodeFuller
  • 30,317
  • 3
  • 63
  • 79
2

Use 'StatusCodeVariable' as available in PowerShell 7.

Refer: https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/invoke-restmethod?view=powershell-7.2

Example:

$getTaskGroupsArgs = @{
       Uri             = $getTaskGroupUri
       Method          = 'GET'
       Headers         = $adoAuthHeader
       UseBasicParsing = $True
       StatusCodeVariable = 'statusCode'

   }
   
   $allTaskGroups = Invoke-RestMethod   @getTaskGroupsArgs
   $statusCode

StatusCodeVariable value is the name of the variable that would be created holding the value of the response code.

Manish Rai
  • 21
  • 3
-2

I saw some people recommend Invoke-WebRequest. You should know that somehow it's based on IE. I get the following error

The response content cannot be parsed because the Internet Explorer engine is not available, or Internet Explorer's first-launch configuration is not complete. Specify the UseBasicParsing parameter and try again.

I know I probably could open IE the first time but the whole idea of writing a script is to avoid dependencies like IE. Invoke-RestMethod does not have this issue.

Baruch Fishman
  • 147
  • 1
  • 2
  • The exception tells you what to do - pass `-UseBasicParsing` to the command. When invoking a REST method, you don't want the `ParsedHtml` property anyway (not to mention that this will cause the Javascript code of the HTML page to run). See https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/invoke-webrequest?view=powershell-5.1 . – Mike Rosoft Mar 18 '22 at 09:25