Advanced ServiceNow Configuration - Post Processing

Post Processing is a feature of Creation Rules that allows for incredible flexibility when creating Incidents or Tasks. If the criteria-driven Creation Rules are not enough for your use case, Connection Center can do almost anything to a newly created Task or Incident using Post Processing and JavaScript.

Enabling Post Processing for a Creation Rule

To use Post Processing select the Post Processing checkbox. When checked, you will be provided with a script field where you can flesh out your more complex use cases.

Post Processing includes an example script baked into the product to give you an idea of what it is capable of and how to use the feature.

Back to top

Variables and Their Use

Post Processing provides you with two variables, scomAlertRecord, and createTask. These provide you with the current alert being processed and the basic new task record created by the Creation Rule respectively. The new task record contains all the details set previously in the Creation Rule UI to allow you to jump straight into customization for your use case. Either of these objects can be updated in the script so you can add to the alert history or change the linked incident (as in the re-opening example below).

This does also mean that you can update or overwrite other alert properties which can be detrimental

To abort the creation of a new Task / Incident entirely, set the createTask cancelCreation property to true as shown in the Re-opening example later.

Variable Properties

These are the default values available on each variable. Customization in ServiceNow may mean that there are more or fewer properties than listed here. By default, if you attempt to assign a value to a property that does not exist the value passed will be dropped.

scomAlertRecord Properties

Property

Equivalent SCOM Alert Property

Additional notes

alertid

Id

alert_activity

N/A

Any alert history events. An example exists under the Reopening an Incident example below.

category

Category

context

Context

customfield1

CustomField1

Dependent on BiDirectional Sync and/or Advanced Updates

customfield10

CustomField10

customfield2

CustomField2

Dependent on BiDirectional Sync and/or Advanced Updates

customfield3

CustomField3

Dependent on BiDirectional Sync and/or Advanced Updates

customfield4

CustomField4

Dependent on BiDirectional Sync and/or Advanced Updates

customfield5

CustomField5

Dependent on BiDirectional Sync and/or Advanced Updates

customfield6

CustomField6

customfield7

CustomField7

customfield8

CustomField8

customfield9

CustomField9

description

Description

hasscomupdate

N/A

Indicates to AlertSync that there is an update to sync back to SCOM

incident

TicketId

Dependent on BiDirectional Sync and/or Advanced Updates

incident_creation_rule

N/A

This is the Creation rule that the alert has matched against.

ismonitoralert

IsMonitorAlert

lastmodified

LastModified

managementgroup

ManagementGroup

managementpackdisplayname

N/A

Drawn from underlying workflow

managementpackname

N/A

Drawn from underlying workflow

monitoringobjectdisplayname

MonitoringObjectDisplayName

monitoringobjectfullname

MonitoringObjectFullName

monitoringobjectid

MonitoringObjectId

monitoringobjectinmaintenancemode

MonitoringObjectInMaintenanceMode

Not so useful on rule based alerts as going into maintenance mode usually closes the alert

monitoringobjectname

MonitoringObjectName

monitoringobjectparentids

N/A

Drawn from underlying object

monitoringobjectpath

MonitoringObjectPath

name

Name

netbioscomputername

NetbiosComputerName

owner

Owner

Dependent on BiDirectional Sync and/or Advanced Updates

parameters

Parameters

principalname

PrincipalName

priority

Priority

repeatcount

RepeatCount

resolutionstate

ResolutionState

resolutionstatename

N/A

severity

Severity

sitename

SiteName

sys_created_by

N/A

ServiceNow property detailing what account created the record (your service account)

sys_created_on

N/A

ServiceNow property detailing when the record was created (not to be confused with timeraised)

sys_id

N/A

ServiceNow unique record ID (a guid without the dashes)

sys_mod_count

N/A

ServiceNow property for modification count

sys_tags

N/A

Servicenow text labels for organisation purposes

sys_updated_by

N/A

ServiceNow property showing who last updated the record

sys_updated_on

N/A

ServiceNow property showing when the record was last updated

timeraised

TimeRaised

The time/datestamp related to the alert being raised in SCOM

timeresolved

TimeResolved

wait_completed

N/A

Used by AlertSync to indicate if the alert went through a wait rule successfully

workflowdisplayname

N/A

Drawn from underlying workflow

workflowname

N/A

Drawn from underlying workflow

createTask Properties

Property

UI label

Additional notes

active

Active

activity_due

Activity due

additional_assignee_list

Assitional assignee list

approval

Approval

approval_history

Approval history

Journal type

approval_set

Approval set

assigned_to

Assigned to

Reference to User (sys_user) table

assignment_group

Assignment group

Reference to Group (sys_user_group) table

business_duration

Business duration

business_service

Service

Reference to Service (cmdb_ci_service) table

calendar_duration

Duration

cancelCreation

N/A

Added temporarily and utilized only by creation rules.

closed_at

Closed

closed_by

Closed by

Reference to User (sys_user) table

close_notes

Close notes

cmdb_ci

Configuration item

Reference to Configuration Item (cmdb_ci) table

comments

Additional comments

Journal Input type

comments_and_work_notes

Comments and Work Notes

Journal List type (you probably want either the comments or work_notes properties)

company

Company

Reference to Company (core_company) table

contact_type

Contact type

contract

Contract

Reference to Contract (ast_contract) table

correlation_display

Correlation display

correlation_id

Correlation ID

delivery_plan

Delivery plan

Reference to Execution Plan (sc_cat_item_delivery_plan) table

delivery_task

Delivery task

Reference to Execution Plan Task (sc_cat_item_delivery_task) table

description

Description

due_date

Due date

escalation

Escalation

expected_start

Expected start

follow_up

Follow up

group_list

Group list

List type referencing Group (sys_user_group) table

impact

Impact

knowledge

Knowledge

location

Location

Reference to Location (cmn_location) table

made_sla

Made SLA

number

Number

The user friendly task/incident number

opened_at

Opened

opened_by

Opened by

Reference to User (sys_user) table

order

Order

parent

Parent

Reference to Task (task) table

priortity

Priority

Function of impact and urgency see default example

reassignment_count

Reassignment count

rejection_goto

Rejection goto

Reference to Task (task) table

route_reason

Route reason

service_offering

Service offereing

Reference to Service Offering (service_offering) table

short_description

Short description

sla_due

SLA due

state

State

sys_class_name

Task type

System Class Name type

sys_created_by

Created by

sys_created_on

Created

sys_domain

Domain

Domain ID type - Used with domain separation

sys_domain_path

Domain Path

Domain Path type - Used with domain separation

sys_id

Sys ID

Table key

sys_mod_count

Updates

sys_tags

N/A

sys_updated_by

Updated by

sys_updated_on

Updated

task_effective_number

Effective number

time_worked

Time worked

universal_request

Universal Request

Reference to Task (task) table

upon_approval

Upon approval

upon_reject

Upon reject

urgency

Urgenency

user_input

User input

watch_list

Watch list

List type referencing User (sys_user) table

wf_activity

Workflow activity

Reference to Workflow Activity (wf_activity) table

work_end

Actual end

work_notes

Work notes

Journal Input type

work_notes_list

Work notes list

List type referencing User (sys_user) table

work_start

Actual start

Back to top

Example Script (Default)

This script is the one shown initially when enabling Post Processing. It updates a Tasks description based on multiple alert fields and then sets its Impact and Urgency based on the alerts' Severity and Priority. This therefore also sets the Tasks priority as this is based on a Tasks Impact and Urgency.

(function postprocessing(scomAlertRecord, createdTask) {
    // Use the below code to further update your incident or task and customize the record created.
    // scomAlertRecord = the inbound SCOM alert from your Management Group, as detailed in the SCOM Alerts table
    // createdTask = the Incident or Task created from the first tab of your creation rule
    // createdTask.cancelCreation = a boolean indicating whether this task creation should be canceled
 
    // Update the description to be the alert name and the server name
    createdTask.description = scomAlertRecord.name + 'on server ' + scomAlertRecord.principalname;
 
    // Programatically setting Impact and Urgency
    var scomPriority = scomAlertRecord.getValue('priority');
    var scomSeverity = scomAlertRecord.getValue('severity');
    if (scomSeverity == 'Error') {
        if (scomPriority == 'High') {
            createdTask.impact = 1;
            createdTask.urgency = 2;
        } else {
            createdTask.impact = 2;
            createdTask.urgency = 2;
        }
    } else if (scomSeverity == 'Warning') {
        if (scomPriority == 'High') {
            createdTask.impact = 2;
            createdTask.urgency = 2;
        } else {
            createdTask.impact = 2;
            createdTask.urgency = 3;
        }
    } else if (scomSeverity == 'Information') {
        createdTask.impact = 3;
        createdTask.urgency = 3;
    }
 
 
})(scomAlertRecord, createdTask);

Back to top

Example Script (Re-open existing task/incident)

This script demonstrates how to re-open a previously resolved Task/Incident that matches our alert and then abort the creation of a new one. It updates a Tasks short description to make it more specific and then searches for resolved tasks that match. If it finds them it puts them to an 'In Progress' state and then links them to our alert and aborts the creation of a new record for the alert.

(function postprocessing(scomAlertRecord, createdTask) {
    // Use the below code to further update your incident or task and customize the record created.
    // scomAlertRecord = the inbound SCOM alert from your Management Group, as detailed in the SCOM Alerts table
    // createdTask = the Incident or Task created from the first tab of your creation rule
    // createdTask.cancelCreation = a boolean indicating whether this task creation should be canceled
 
    // ---------------------------------------------
    // Re-opening existing task/incident example script
    // ---------------------------------------------
 
    //Figure out what table we are using for this creation rule
    var Table = createdTask.getTableName();
     
    // Create a GlideRecord object which we'll use for searches
    var gr = new GlideRecord(Table);
     
    // ------------------------------------------------------------------
    // Configure the incident values, combinding some SCOM properties
    // ------------------------------------------------------------------
     
    // We will append the object name to the short description for user convinence
    createdTask.short_description = scomAlertRecord.name + ' - ' + scomAlertRecord.monitoringobjectfullname;
     
    // Short description must match and state must be 6 (Resolved)
    gr.addQuery('short_description', createdTask.short_description);
    gr.addQuery('state', 6);
  
    // Execute the query and proceed to check for results 
    gr.query();
     
    // ------------------------------------------------------------------
    // Create or update a task based on the search results
    // ------------------------------------------------------------------
  
    if (gr.next()) {
        // Existing record found, change the status to In Progress
        gr.state = 2;
        gr.work_notes = 'Re-opened from SCOM Alert';
        gr.update('Re-opened from SCOM Alert');
  
        // Store the existing record to our SCOM record
        scomAlertRecord.incident = gr.sys_id;
         
        // Add note to alert history tab to indicate what happened there as well
        scomAlertRecord.alert_activity = 'Found existing ' + Table + ' ' + gr.number;
         
        // Cancel the creation of new task as we have found an existing one that matches
        createdTask.cancelCreation = true;
  
    } else {
        // No matching incidents, continue with creation
    }
})(scomAlertRecord, createdTask);

Back to top

Example Script (Link to webpage/dashboard)

This script demonstrates how to add work notes with links in them to a third-party source. The link is built up using properties pushed up with the alert, so as long as the target is based around something pushed in the alert record you can build this up as you see fit. Examples might be linking to the SCOM web console or a third-party SCOM dashboard should that be desirable (perhaps to quickly get at performance data). Similarly, you could use this to link off to something like SharePoint, Confluence, or an internal Wiki if there would be further context there. Finally, if this is coming from something like an Azure, AWS, something that knows about IPMI, etc. you could potentially link directly to their portal using the monitoring object name or details in the alert context.

(function postprocessing(scomAlertRecord, createdTask) {
    // Use the below code to further update your incident or task and customize the record created.
    // scomAlertRecord = the inbound SCOM alert from your Management Group, as detailed in the SCOM Alerts table
    // createdTask = the Incident or Task created from the first tab of your creation rule
    // createdTask.cancelCreation = a boolean indicating whether this task creation should be canceled
 
    // ------------------------------------------------------------------
    // Linking to third party dashboarding example script
    // ------------------------------------------------------------------
     
    // Set a variable to build up the note in
    var Worknote;
     
    // Set our base addresses so we don't have to repeat ourselves 
    var Address = 'https://monitoring.domain.tld/drilldown';
    var AzurePortal = 'https://portal.azure.com#@domain.tld/resource';
     
    // Build up a link to the alert dipping into HTML where required
    // On click open it in a new window
    Worknote = 'Alert Dashboard: [code]<a href="' + Address + '/scomalert?id=' + scomAlertRecord.alertid.toString() + ' "target="_blank">' + scomAlertRecord.name.toString() + '</a>[/code]' + '\n';
     
    // Build up a link to the object dipping into HTML where required
    // On click open it in a new window
    Worknote = Worknote + 'Object Dashboard: [code]<a href="' + Address + '/scomobject?id=' + scomAlertRecord.monitoringobjectid.toString() + ' "target="_blank">' + scomAlertRecord.monitoringobjectdisplayname.toString() + '</a>[/code]' + '\n';
     
    // If this is from the Azure Management pack link directly to the portal
    // You would probably make checks like this from the Creation Rule filter 
    // However if there is an indicator in the alert context or CI you would probably make that check here instead
    if (scomAlertRecord.managementpackname == 'Microsoft.SystemCenter.MicrosoftAzure') {
        Worknote = Worknote + 'Azure Portal: [code]<a href="' + AzurePortal + scomAlertRecord.monitoringobjectname.toString() + ' "target="_blank">' + scomAlertRecord.monitoringobjectdisplayname.toString().split(' ')[0] + '</a>[/code]' + '\n';
    }
     
    // Assign the details built above to a worknote on the raised task
    createdTask.work_notes = Worknote;
     
})(scomAlertRecord, createdTask);

Back to top

Example Script (Raise a problem on repeated alerts)

This script demonstrates one of the options for raising a problem automatically. We look up all instances of the alert on the object in the last 30 days (using a GlideSystem method) that generated a task/incident. If there are 4 or more existing records we need to make sure a problem exists. If there is an existing problem linked to the newest matching record we simply link to that one. If there is no problem on the newest incident we raise a new problem (assuming the required permissions are present) and link this problem to all records that don’t already have a problem.

(function postprocessing(scomAlertRecord, createdTask) {
    // Use the below code to further update your incident or task and customize the record created.
    // scomAlertRecord = the inbound SCOM alert from your Management Group, as detailed in the SCOM Alerts table
    // createdTask = the Incident or Task created from the first tab of your creation rule
     
    var grAlert = new GlideRecord("x_oklt_cookdown_sc_scom_alerts");
     
    // Find alerts from the last 30 days
    grAlert.addQuery('timeraised', '>=' ,gs.beginningOfLast30Days());
     
    // With the same Object ID
    grAlert.addQuery('monitoringobjectid',scomAlertRecord.monitoringobjectid);
     
    // With the same Rule/Monitor
    grAlert.addQuery('workflowname',scomAlertRecord.workflowname);
     
    // Where a task/incident was raised
    grAlert.addNotNullQuery('incident');
     
    // Put the first record rasied first
    grAlert.orderByDesc('timeraised');
     
    // Execute Query
    grAlert.query();
    grAlert.next();
     
    // We assume here that if the newest Task/Incident doesn't have a problem that none of them do
    // You may need additional logic here if this does not fit your scenario
     
    if ((grAlert.getRowCount() >= 4) && (grAlert.incident.getRefRecord().problem_id != '')) {
        // If this is the 5th (or greater) ticket and there is an existing problem
         
        //Log the scenario (pulling details from linked records)
        scomAlertRecord.alert_activity = "Found " + grAlert.getRowCount().toString() + " matching records and an existing problem: " + grAlert.incident.getRefRecord().problem_id.getRefRecord().number;
         
        // We have previously raised a problem, link it to the new Incident/Task
        createdTask.problem_id = grAlert.incident.getRefRecord().problem_id;
         
    } else if (grAlert.getRowCount() >= 4) {
        // If this is the 5th (or greater) ticket and there is no existing problem
         
        //Log the scenario
        scomAlertRecord.alert_activity = "Found " + grAlert.getRowCount().toString() + " matching records and no existing problem";
 
        // Start work against the problem table
        var grPrb = new GlideRecord("problem");
         
        // Start the new record
        grPrb.initialize();
         
        // Short description is mandatory 
        // You may wish to populate other fields, the createdTask properties can be a good reference point as they should line up
        grPrb.short_description = "Problem raised to deal with repeated " + scomAlertRecord.name + " alerts from " + scomAlertRecord.monitoringobjectdisplayname;
         
        // Set the first reported task to the incident raised by the first recorded SCOM alert
        grPrb.first_reported_by_task = grAlert.incident;
         
        // Insert the record and link the task
        createdTask.problem_id = grPrb.insert();
         
        // Log the created problem number
        scomAlertRecord.alert_activity = "Raised a new problem: " + grPrb.number;
        do {
            // Loop through each alert matching alert
             
            // Look up the incident
            var incident = grAlert.incident.getRefRecord();
             
            // If no existing problem, set the corresponding problem
            // Despite the assumtions earlier we don't want to clobber other problems if they exist
            if (! incident.problem_id) {
                // Set the problem
                incident.problem_id = createdTask.problem_id;
                 
                // Update the incident
                incident.update();
            }
 
        } while (grAlert.next());
    }
    else {
        // Log the scenario
        scomAlertRecord.alert_activity = "Found " + grAlert.getRowCount().toString() + " matching records, not raising a problem";
    }
     
    // Finish and let the creation rule deal with creating the current incident
})(scomAlertRecord, createdTask);

Back to top

Further Reading and Next Steps

Ultimately scripting in our Creation Rules is very customizable and will therefore require testing to make sure that it fits your requirements. If you haven’t looked at them already we would recommend looking at the Testing, Tips, and Tricks for ServiceNow page, as this has a number of handy shortcuts from our testing, support, and engineering teams that should make this a bit easier!

Hopefully, this all goes smoothly, but you may also wish to familiarize yourself with our Troubleshooting ServiceNow page.

You may also wish to look at the official ServiceNow Documentation on scripting or one of our favorite ServiceNow scripting blogs: The ServiceNow Guru