2

This is my first post on Stackoverflow, please let me know if my post is not formatted or submitted correctly, etc. I am attempting to use powershell to connect to my ServiceNow instance and POST a service catalog request. However, I am receiving error (400) Bad Request:


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


Thus far, I have been able to successfully POST a service catalog request through the ServiceNow REST API Explorer using the URI:

POST https://myinstance.service-now.com/api/sn_sc/v1/servicecatalog/items/3a05b357db2443009906540adc961945/order_now

with a raw response body of:

{"sysparm_quantity":"1","variables":{"requested_for":"Guest","Request_Type":"New Account","website_login":"2437ffdbdb2443009906540adc96198c"}}

I have also been able to use Powershell to successfully POST an Incident to ServiceNow. Taking this into consideration, I believe I do not have any access issues, but rather a syntax / formatting issue with the $body portion of my code. Any help would be greatly appreciated!


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

# 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://myinstance.service-now.com/api/sn_sc/servicecatalog/items/3a05b357db2443009906540adc961945/order_now"

# Variables
$RequestedFor = "Guest"
$RequestType = "New Account"
$Vendor1 = "2437ffdbdb2443009906540adc96198c"

# Specify request body
$body = @{
sysparm_quantity = "1"
Requested_For = $RequestedFor
Request_Type = $RequestType
website_login = $Vendor1
}

$bodyJson = $body | ConvertTo-Json;

#Convert to UTF8 array to support special chars such as the danish "�","�","�"
$utf8Bytes = [System.Text.Encoding]::UTf8.GetBytes($bodyJson)

# Send HTTP request
$response = Invoke-RestMethod -Headers $headers -Method Post -Uri $uri -Body $utf8Bytesn -ContentType "application/json" -UseBasicParsing

$response.RawContent



Per user Saj's advice I've tested POSTing a request to ServiceNow from Fiddler. The request was created successfully in ServiceNow. Please see the captured Fiddler session below.

POST https://myinstance.service-now.com/api/sn_sc/v1/servicecatalog/items/3a05b357db2443009906540adc961945/order_now HTTP/1.1
Host: myinstance.service-now.com
User-Agent: Fiddler
Content-Type: application/json
Content-Length: 142
Authorization: Basic myauthorizationcode

{"sysparm_quantity":"1","variables":{"requested_for":"Guest","Request_Type":"New Account","website_login":"2437ffdbdb2443009906540adc96198c"}}

HTTP/1.1 200 OK
Set-Cookie: JSESSIONID=ED953CDDB8BB202C5B8D55558003F9B6;Secure; Path=/; HttpOnly
Set-Cookie: glide_user="";Secure; Expires=Thu, 01-Jan-1970 00:00:10 GMT; Path=/; HttpOnly
Set-Cookie: glide_user_session="";Secure; Expires=Thu, 01-Jan-1970 00:00:10 GMT; Path=/; HttpOnly
Set-Cookie: glide_user_route=glide.c87651ce1f062e6286a35c971e448b2c;Secure; Expires=Thu, 04-Apr-2086 19:33:19 GMT; Path=/; HttpOnly
X-Is-Logged-In: true
Set-Cookie: glide_session_store=B598F91313FC1340B17EDB128144B0E7;Secure; Expires=Sat, 17-Mar-2018 16:49:12 GMT; Path=/; HttpOnly
Pragma: no-store,no-cache
Cache-control: no-cache,no-store,must-revalidate,max-age=-1
Expires: 0
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked
Date: Sat, 17 Mar 2018 16:19:13 GMT
Server: ServiceNow
Set-Cookie: BIGipServerpool_myinstance=2441092106.40510.0000; path=/
Strict-Transport-Security: max-age=63072000; includeSubDomains

59
{"result":{"request_number":"REQ0026993","request_id":"7598fd1313fc1340b17eda128144b043"}
1
}
0
  • Isn't Order Now deprecated ? what version are you on Kingston/Jarkata ? – fuzzybear Mar 17 '18 at 00:13
  • Not to my knowledge. I'm on Istanbul. I would think that if I can create a Request via the REST API Explorer through the Order Now aka Buy Item POST method that it is still in effect. – Dustdreams27 Mar 17 '18 at 00:44
  • I added a try / catch statement to my code and can now see more information on the error. It is showing the following: @{message=Invalid Quantity value; detail=} – Dustdreams27 Mar 17 '18 at 00:54
  • Can you capture and post a working request from fiddler ? – fuzzybear Mar 17 '18 at 01:25
  • @saj - I was able to successfully POST a request to ServiceNow from Fiddler. I was also able to capture a failed POST from powershell to ServiceNow via the Fiddler stream. The failed powershell POST still yields a 400 response and after making some slight adjustments to the $Body, I am now receiving an error message "Mandatory Variables are required". The only mandatory variables required by the catalog item I am targeting are "requested_for" and "Request_Type". Please see my original post, I've edited it and added the captured, successful Fiddler session. – Dustdreams27 Mar 17 '18 at 23:23
  • Ok great if we can capture the successful post we can almost certainly work out what to do, well done with fiddler, what we need to see is the request data, double click the item and goto the JSON tab, is the JSON you have posted under the authorization header the same ? – fuzzybear Mar 18 '18 at 02:08

1 Answers1

1

Thanks to @Saj for leading me in the right direction and recommending Fiddler to help examine my request and response to ServiceNow. The issue was that I was not specifying what should be defined as variables in my json body. E.g.

$body = @{
'sysparm_quantity' = '1'
'variables' = @{
'requested_for' = "$RequestedFor"
'Request_Type' = $RequestType
'website_login' = $Vendor1
}}

I also removed the section of code that converted the json to a UTF8 array as it was not necessary.

$utf8Bytes = [System.Text.Encoding]::UTf8.GetBytes($bodyJson)