How to: Submitt Request offering using Powershell
In this guide we will have a look on how you can fill and submit an existing request offering using the Invoke-WebRequest Powershell commandlet and our ITSM Portal V3 with Windows Authentication.
The goal is to understand how you can make use of the ITSM Portal’s API to submit request offerings from basically everywhere (e.g. Powershell, Postman, PowerAutomate, Azure Functions and many more)
Prerequisites
To follow this guide you should have the following:
* ITSM Portal V3 installed on a server
* ITSM Portal V3 configured to use Windows Authentication
* Access to the SCSM Console
* PowerShell ISE
Create Request Offering
Let’s start with creating a Request Offering which we want to submitt with PowerShell eventually.
You should be familiar with how to create ROs as this guide will not go too much into details.
For this guide we will create a fairly simple offering with the following prompt types:
* Textbox
* Boolean
* Decimal Number
* DateTime Picker
* Instance Picker (e.g. User picker)
To do this, open your SCSM Console, navigate to Library\Service Catalog\Request Offerings\All Request Offerings
and execute the Task Create RO for ITSM Portal
Configure your Request offering as shown in below screenshots:
General
User Prompts
Configure Prompts
Text
Default Settings
Boolean
Default Settings
Decimal Number
Default Settings
DateTime Picker
Default Settings
User Picker
Layout
Map Prompts
Map all your prompts to any property that fits.
Knowledge Articles
Skip this section
Publish
Make sure you change the Offering status to Published
Service Offerings
Add your Request Offering to an existing Service Offering.
Skip this step if you do not want this Request Offering to be available in your ITSM Portal Service catalog.
Summary
Check the summary and finnaly create your Request Offering.
Acquire important Request Offering Infos
To craft the correct API calls we must first acquire the ID and the structure of the HTTP-Request Body of our Request Offering.
To do this, open the request offering in your ITSM Portal V3
Fill all prompts of your offering with more or less meaningfull data.
Before Submitting open your browser’s dev-tools (usually by pressing F12). Go to the Network tab of the dev-tools and make sure that the browser is recording your network traffic
Now submit your request and observe the network traffic. You should find a request to /api/EndUser/ServiceCatalog/SubmitRequest/[the GUID of your request]
Note down this Request URL for later use in your script.
Next, look out for the Form Data
Section, there you will find the answers to all the prompts and their respective IDs.
As you can see, the answers to the default
prompts like text or decimal are fairly simple.
But the answer for the Query Results is a bit more complicated - for now, just note down the IDs of your prompts (f_[GUID]
), we will have a look at the Query Results later on.
Submit using Powershell
Now that we have noted the request offering ID as well as the IDs of its prompts, we can start creating our Powershell script
API Url & Authentication
Start with declaring variables with the Request Url and account details to authenticate.
Make sure the account specified is permitted to submit requests in the ITSM Portal.
Then, create a credential object from those details.
$domain = 'http://yourportaldomain.com/api/EndUser/ServiceCatalog/SubmitRequest/d1a50625-4d37-5427-752e-e48425974f33'
$user = 'domain\user'
$pass = 'Pa$$w0rd'
$secpw = ConvertTo-SecureString $pass -AsPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential($user, $secpw)
The $cred object will be used later when calling the API
Declaring the user and password in cleartext is not recommended in production.
Make use of the -UseDefaultCredentials switch of the Invoke-WebRequest commandlet and execute the powershell script with a user permitted to submit requests in the ITSM Portal.
https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/invoke-webrequest?view=powershell-5.1Depending on the tool you are using it may be difficult to setup the correct authentication.
The ITSM Portal in Windows authentication mode requires NTLM authentication which powershell handles just nicely.
Postman also includes a BETA feature to authenticate using NTLM
However, other tools might not provide any option to authenticate using NTLM
Form-data
Unfortunately, PowerShell does not provide any function to create a form-data body to send to an API, so we must create that by ourselves.
Start with a new hashtable
$form = @{
}
Then add in the IDs of your prompts as keys of the hashtable and their values.
$form = @{
'f_b90737bd4a054daf8c328f2f2297711b' = 'Hallo Velo'
'f_9023e645d2f14b4d820e0589ff712a1a' = 'True'
'f_6df2e26b8f09430dacfb00f4e673bf57' = 0.5
'f_d74be70f3ab344faa14c232ee4c5ca84' = "2021-01-05T23:00:00.000Z"
}
Note that boolean and datetime values must be converted to String.
Also, make sure the DateTime format is exactly as shown above, otherwise you will receive a 500 Error status from the API
So far so good. But what about the Query results prompt?
Open image-20210129-144638.png
The value of the Query results prompt is a json object converted to string - so we will do the same thing!
However, there is some info that can be ignored. You must provide a value for “answers”, all others may be omitted.
The answer
object itself is an array of json-objects. Depending on your Query results configuration this object will hold one or multiple items.
In our case this array holds one item - the user we want to select.
So, let us construct this thing using hashtables and lists, convert it to a json string, and add it to our form-data, like so:
$form = @{
'f_b90737bd4a054daf8c328f2f2297711b' = 'Hallo Velo' #Text
'f_9023e645d2f14b4d820e0589ff712a1a' = 'True'#Bool
'f_6df2e26b8f09430dacfb00f4e673bf57' = 0.5 #Decimal
'f_d74be70f3ab344faa14c232ee4c5ca84' = "2021-01-05T23:00:00.000Z"
'f_fa2502757895488db7b522e187e47d33' = (
@{
answers = @(
@{'$Id$' = 'd784e8c3-61a4-62db-a704-71642ddf12b6'; 'DisplayName' = 'Test User 1'}
)
}
) | ConvertTo-Json -Depth 4 -Compress
}
The keys of the object in the answers array are defined by the query results configuration.
You must define all keys that you could observe in the form-data while submitting a request using your browser (in this example it is $Id$ and DisplayName), otherwise the API will return a 500 Error.
Now that we have our hashtable prepared with the data we want to send, we must convert it into an actual url encoded form-data string that we can send to the API.
A url encoded form-data string is structured like the following example:
key1=value1&key2=value2&key3=value3 ...
So all we need to do is to convert each key-value pair of our hashtable to a string with the key first, then a = followed by the url encoded value and finnaly join all these strings together with a & in between them.
$form = $form.Keys | % { "$_=$([System.Web.HttpUtility]::UrlEncode($form.Item($_)))"}
$form = $form -join "&"
Url encoding is required to be able to send special characters like whitespaces which are not allowed in a Url as such.
Submit Request
Now we have everything we need to submit a request offering.
Use the Invoke-WebRequest
commandlet to send your request like below:
Invoke-WebRequest $domain -Credential $cred -ContentType 'application/x-www-form-urlencoded' -body $form -Method POST
After successfully submitting your request you can go check it out in the ITSM Portal:
Appendix
Complete powershell example script
$domain = 'http://yourportaldomain.com/api/EndUser/ServiceCatalog/SubmitRequest/d1a50625-4d37-5427-752e-e48425974f33'
$user = 'domain\user'
$pass = 'Pa$$w0rd'
$secpw = ConvertTo-SecureString $pass -AsPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential($user, $secpw)
$form = @{
'f_b90737bd4a054daf8c328f2f2297711b' = 'Hallo Velo' #Text
'f_9023e645d2f14b4d820e0589ff712a1a' = 'True'#Bool
'f_6df2e26b8f09430dacfb00f4e673bf57' = 0.5 #Decimal
'f_d74be70f3ab344faa14c232ee4c5ca84' = "2021-01-05T23:00:00.000Z"
'f_fa2502757895488db7b522e187e47d33' = (
@{
answers = @(
@{'$Id$' = 'd784e8c3-61a4-62db-a704-71642ddf12b6'; 'DisplayName' = 'Test User 1'}
)
}
) | ConvertTo-Json -Depth 4 -Compress
}
# Convert Form Hash to the correct HTML body
# The data must be sent as "form-data" string which looks like this:
#
# key=value&key2=value2&key3=value3 etc.
#
# Special characters, such as whitespaces must be encoded, therfore the UrlEncode method below
$form = $form.Keys | % { "$_=$([System.Web.HttpUtility]::UrlEncode($form.Item($_)))"}
$form = $form -join "&"
Invoke-WebRequest $domain -Credential $cred -ContentType 'application/x-www-form-urlencoded' -body $form -Method POST
Troubleshooting
Error 500 returned by API
This usually happens if soemthing is wrong with the form-data you are trying to submit.
To get further info on what exactly is wrong with your form-data, check the ITSM Portal’s log files, located at <youritsmportalinstallationfolder>\Logs
after your failed submit attempt.
Submitted request shows empty userinput
This may happen if the ITSM Portal’s API did not receive any form-data at all.
Carefully check your scripts for errors. Maybe you forgot to set the Content-Type
to application/x-www-form-urlencoded
?