Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OneLogin REST API with PowerShell's Invoke-RestMethod

I'm working against the OneLogin REST API and can't seem to get any calls with a PUT method working. When I test in Postman, I can pass a raw JSON body like this:

{
   "role_id_array":  [
                        115028
                     ]
}

to the endpoint:

https://api.us.onelogin.com/api/1/users//add_roles

This works just fine. However, when I attempt to do the same with PowerShell's Invoke-RestMethod command, I'm getting 400 Bad Request errors. My code looks like this:

$Splat = @{
    Method      = $Method
    Uri         = https://api.us.onelogin.com/api/1/users/12345678/add_roles
    ContentType = "application/json"
    Headers     = @{authorization = "bearer:$($Token.access_token)"}
    Body        = @{role_id_array = @(123456)}
}

Invoke-RestMethod @Splat

So far I've had no issues with any GET calls, only with PUT. Also, if I run the Body hashtable that I'm passing in through ConvertTo-Json, the output looks just like the above working example. Does anyone have any thoughts on why this doesn't work?

like image 399
Matt McNabb Avatar asked Sep 24 '26 09:09

Matt McNabb


1 Answers

I was able to get a PUT to work!

How to get rich error response data from Invoke-RestMethod

First, I used this blog post here which has an excellent method to retrieve the full error message of an Invoke-RestMethod or WebRequest cmdlet.

In his method, first define a Function called Failure.

function Failure {
    $global:helpme = $body
    $global:helpmoref = $moref
    $global:result = $_.Exception.Response.GetResponseStream()
    $global:reader = New-Object System.IO.StreamReader($global:result)
    $global:responseBody = $global:reader.ReadToEnd();
    Write-Host -BackgroundColor:Black -ForegroundColor:Red "Status: A system exception was caught."
    Write-Host -BackgroundColor:Black -ForegroundColor:Red $global:responsebody
    Write-Host -BackgroundColor:Black -ForegroundColor:Red "The request body has been saved to `$global:helpme"
    break
}

Then, wrap all of your Invoke-RestMethod calls in a try Catch block like this.

try { 
    $e = Invoke-WebRequest 'https://api.us.onelogin.com/api/1/users/$id' `
        -Headers  @{ Authorization = "bearer:$token" } `
        -Body ( @{ phone = "7709746046" } | ConvertTo-Json ) `
        -Method Put `
        -ErrorAction:Stop `
        -ContentType 'application/json' 
} 
catch {Failure}

Now when you run into an error, you can see the actual message, like this

> Status: A system exception was caught.
{"status":{"error":true,"code":400,"type":"bad request","message":{"description":"notes is not a valid attribute for user model","attribute":"notes"}}}
The request body has been saved to $global:helpme

This was super helpful in helping me get rid of the errors I was encountering, and I was able to update a user entry using a PUT verb and get it to work.

Fixing your issue

I only had to make two changes to your code to get this to work.

First, put quotes around the URI, as your example code didn't have them and you must have quotes around strings in a hashtable.

Finally, pipe your body content to ConvertTo-JSON, otherwise the data is sent over as a string, as you found in Fiddler.

With those two changes, here's my request and the response

$Splat = @{
    Method      = 'PUT'
    Uri         = 'https://api.us.onelogin.com/api/1/users/27697924/add_roles'
    ContentType = "application/json"
    Headers     = @{authorization = "bearer:$token" }
    Body        = @{role_id_array = @(143175)} | ConvertTo-Json
}

try {Invoke-RestMethod @Splat -ErrorAction Stop }
catch {Failure}

Here's the response:

status                                                 
------                                                 
@{type=success; message=Success; error=False; code=200}

Update: we did it, this has now been fixed!

If you think PowerShell should present the actual server response for a non 200 status code, then help draw attention to this open issue on the PowerShell project page on Github.

Add your feedback or thumbs up it, and we might be able to get this changed in a future release of the language.

This issue is now fixed as of PowerShell v6.1

like image 54
FoxDeploy Avatar answered Sep 26 '26 02:09

FoxDeploy