REST API Explorer - Powershell Export problem and Error (400)

Ian13
Kilo Contributor

Hi All,

 

I’ve recently been attempting to build an automation workflow for my client who uses Snow as their Service Desk Ticketing Platform and am having some troubles with the inbuilt REST API Explorer’s export function for Powershell scripts…

 

Specifically I am having problems with the syntax of the generated output and sending a PUT request to snow using PS. Just for a bit of context, I can run GET requests perfectly fine since they don’t use $body for anything so I just strip those bits out and they work fine, however PUT commands are very different.

 

Upon building my Code Sample in the REST API Explorer, I get this:

# Eg. User name="admin", Password="admin" for this code sample.
$user = "admin"
$pass = "admin"

# Build auth header
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $user, $pass)))

# Set proper headers
$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$headers.Add('Authorization',('Basic {0}' -f $base64AuthInfo))
$headers.Add('Accept','application/json')
$headers.Add('Content-Type','application/json')

# Specify endpoint uri
$uri = "https://[DEVNUMBER].service-now.com/api/now/table/incident/3a678d181b0840106bc9fc88cc4bcbde"

# Specify HTTP method
$method = "put"

# Specify request body
{request.body ? "$body = \"" :""}}{\"state\":\"6\",\"close_notes\":\"This Ticket has been Closed Automatically\",\"close_code\":\"Solved (Permanently)\"}"

# Send HTTP request
$response = Invoke-WebRequest -Headers $headers -Method $method -Uri $uri -Body $body

# Print response
$response.RawContent

Unfortunately the request body for the above code is malformed and is therefore, invalid PowerShell syntax.

 

I have attempted to fix this in various ways, one of which includes specifically defining my $body variable like so:

# Eg. User name="admin", Password="admin" for this code sample.
$user = "admin"
$pass = "admin”

# Build auth header
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $user, $pass)))

# Set proper headers
$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$headers.Add('Authorization',('Basic {0}' -f $base64AuthInfo))
$headers.Add('Accept','application/json')
$headers.Add('Content-Type','application/json')

# Specify endpoint uri
$uri = "https://[DEVNUMBER].service-now.com/api/now/table/incident/7fb3709e1bc000106bc9fc88cc4bcb94"

# Specify HTTP method
$method = "put"

# Specify request body
$body = @{
"state" = "6"
"close_code" = "Solved (Permanently)"
"close_notes" = "This Ticket has been Closed Automatically"
}


# Send HTTP request
$response = Invoke-WebRequest -Headers $headers -Method $method -Uri $uri -Body $body

# Print response
$response.RawContent 

However… Even this is giving me grief and I am not sure how to continue troubleshooting this problem with the following output when running in PowerShell:

Invoke-WebRequest : The remote server returned an error: (400) Bad Request.
At line:29 char:13
+ $response = Invoke-WebRequest -Headers $headers -Method $method -Uri  ...
+             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-WebRequest], WebException
    + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand 

Could anyone provide some functional PUT requests in Powershell as an example so I can see where I am going wrong? Perhaps I've written something with an incorrect syntax... I am capable of running GET Commands perfectly fine since the ones constructed in the explorer don't use the $body argument so I could just comment that out.

 

I would appreciate any support you could give on this issue.

 

Thanks,

 

Ian.

1 ACCEPTED SOLUTION

Nitin Panchal
Tera Guru

Hi Ian, 

First convert the body message that your are passing to json like below

$body = @{
"state" = "6"
"close_code" = "Solved (Permanently)"
"close_notes" = "This Ticket has been Closed Automatically"
}

$UpdateBodyJSON=$body | ConvertTo-Json

 Then invoke rest message like below 

$response = Invoke-RestMethod -Headers $headers -Method $method -Uri $uri -Body $body -ContentType "application/json"

Also check if service account has role snc_platform_rest_api_access role. Also make sure that servicenow incident table has write ACL for role  snc_platform_rest_api_access

 

Thanks, 
Nitin

View solution in original post

3 REPLIES 3

Nitin Panchal
Tera Guru

Hi Ian, 

First convert the body message that your are passing to json like below

$body = @{
"state" = "6"
"close_code" = "Solved (Permanently)"
"close_notes" = "This Ticket has been Closed Automatically"
}

$UpdateBodyJSON=$body | ConvertTo-Json

 Then invoke rest message like below 

$response = Invoke-RestMethod -Headers $headers -Method $method -Uri $uri -Body $body -ContentType "application/json"

Also check if service account has role snc_platform_rest_api_access role. Also make sure that servicenow incident table has write ACL for role  snc_platform_rest_api_access

 

Thanks, 
Nitin

One mild change but your answer did bring me back onto the right track, I can't believe I missed converting the object to Json.

Thanks very much.

$body = $body | ConvertTo-Json

CMehta
Kilo Contributor

Thank you Nitin!!