In my last blog I explained basics of “Scripted REST API” – Now, let me show the simple trick to query all incidents and changes for the given configuration item. In my case CAR-3 is a CI which has one incident record and for our demo lets create a Scripted REST API to fetch required information.
Note: You can think about Database views for your environment. I will cover that in my upcoming blog.
Our goal is to achieve below output (2 incidents [Created for a demo] for given CI [CAR-3] and required CI field information)
{ "result": { "incidentRecord": [ { "number": "INC0010005", "state": "New", "opened_at": "2018-07-20 12:29:00" }, { "number": "INC0010006", "state": "New", "opened_at": "2018-07-20 12:29:00" } ], "cmdbRecord": [ { "name": "Car-3", "asset_tag": "P1000113", "managed_by": "Bow Ruggeri" } ] } }
System Definitions (Script Includes)
var getconfigurationitemdetails = Class.create(); getconfigurationitemdetails.prototype = { getIncidentRecords: function (CIName) { try { var incidentRecord = []; var gr = new GlideRecord('incident'); var queryString = 'cmdb_ciSTARTSWITH' + CIName; gr.addEncodedQuery(queryString); gr.query(); while (gr.next()) { incidentRecord.push({ 'number': gr.number + '', 'state': gr.state.getDisplayValue() + '', 'opened_at': gr.opened_at }); } return incidentRecord; } catch (e) { gs.error('error=', e); } }, getCMDBRecords: function (CIName) { try { var cmdbRecord = []; var gr = new GlideRecord('cmdb_ci'); gr.addQuery('name', CIName); gr.query(); if (gr.next()) { cmdbRecord.push({ 'name': gr.name + '', 'asset_tag': gr.asset_tag.getDisplayValue() + '', 'managed_by': gr.managed_by.getDisplayValue() }); return cmdbRecord; } } catch (e) { gs.error('error=', e); } } };
Scripted REST API
(function process(/*RESTAPIRequest*/ request, /*RESTAPIResponse*/ response) { var incidentRecord = new getconfigurationitemdetails().getIncidentRecords(request.pathParams.CIName); var cmdbRecord = new getconfigurationitemdetails().getCMDBRecords(request.pathParams.CIName); return { 'incidentRecord': incidentRecord, 'cmdbRecord': cmdbRecord }; })(request, response);
Now, comes our PowerShell code!
param( $CIName = 'Car-3' ) try { $Uri = "https://dev42835.service-now.com/api/253124/getconfigurationitemdetails/$($CIName)" $admin = "admin" $password = "admin" | ConvertTo-SecureString -AsPlainText -Force $Credential = New-Object pscredential -ArgumentList ($admin , $password) $Results = Invoke-RestMethod -Uri $Uri -Method Get -Credential $Credential $Results.result.incidentRecord } catch { $_.Exception }
To get the full result as JSON use the below snippet.
$Results.result | ConvertTo-Json
Output
{ "incidentRecord": [ { "number": "INC0010005", "state": "New", "opened_at": "2018-07-20 12:29:00" }, { "number": "INC0010006", "state": "New", "opened_at": "2018-07-20 12:29:00" } ], "cmdbRecord": [ { "name": "Car-3", "asset_tag": "P1000113", "managed_by": "Bow Ruggeri" } ] }
Summary : By implementing this we can avoid multiple web requests to servicenow instance. For example if we use OOB REST API we need to send web requests as illustrated below
- Query incident table.
- Query cmdb_ci table
- Send request(s) to get profile information which are masked as ID (Example managed_by , state etc)