Skip to content
incident-management logo

Incident Management for ServiceNow

incident-management

Manage ServiceNow incidents — creation with impact/urgency priority calc, auto-assignment by category, reassignment tracking, major incident declaration with bridge calls, time-based escalation, MTTR metrics.

groeimetai/snow-flow0installs78stars

SKILL.md

Full skill instructions

Incident Management for ServiceNow

Incident Management restores normal service operation as quickly as possible while minimizing business impact.

Incident Lifecycle

New (1)
    ↓
In Progress (2)
    ↓ ← On Hold (3)
Resolved (6)
    ↓
Closed (7)

Cancelled (8) ← Can occur from New/​In Progress

Key Tables

TablePurpose
incidentIncident records
incident_taskSub-tasks for incidents
incident_alertRelated alerts
problemRelated problems

Creating Incidents (ES5)

Basic Incident Creation

// Create incident (ES5 ONLY!)
var incident = new GlideRecord("incident")
incident.initialize()

// Required fields
incident.setValue("caller_id", callerSysId)
incident.setValue("short_description", "Email not working")
incident.setValue("description", "User cannot send or receive emails since this morning")

// Classification
incident.setValue("category", "software")
incident.setValue("subcategory", "email")
incident.setValue("impact", 2)
incident.setValue("urgency", 2)
// Priority is calculated automatically from impact/​urgency

// Assignment
incident.setValue("assignment_group", getGroupSysId("Email Support"))

// Optional: affected CI
incident.setValue("cmdb_ci", emailServerSysId)

var incidentSysId = incident.insert()
gs.info("Created incident: " + incident.getValue("number"))

Priority Matrix

// Priority calculation (ES5 ONLY!)
// Priority = Impact x Urgency matrix
var priorityMatrix = {
  "1-1": 1, // High Impact + High Urgency = Critical
  "1-2": 2, // High Impact + Medium Urgency = High
  "1-3": 3, // High Impact + Low Urgency = Moderate
  "2-1": 2, // Medium Impact + High Urgency = High
  "2-2": 3, // Medium Impact + Medium Urgency = Moderate
  "2-3": 4, // Medium Impact + Low Urgency = Low
  "3-1": 3, // Low Impact + High Urgency = Moderate
  "3-2": 4, // Low Impact + Medium Urgency = Low
  "3-3": 5, // Low Impact + Low Urgency = Planning
}

function calculatePriority(impact, urgency) {
  var key = impact + "-" + urgency
  return priorityMatrix[key] || 4
}

Incident Assignment (ES5)

Auto-Assignment Rules

// Assignment rule script (ES5 ONLY!)
// Business Rule: before, insert, incident

;(function executeRule(current, previous) {
  // Skip if already assigned
  if (current.assignment_group) {
    return
  }

  var group = determineAssignmentGroup(current)
  if (group) {
    current.assignment_group = group

    // Optionally assign to on-call
    var onCallUser = getOnCallUser(group)
    if (onCallUser) {
      current.assigned_to = onCallUser
    }
  }
})(current, previous)

function determineAssignmentGroup(incident) {
  var category = incident.getValue("category")
  var subcategory = incident.getValue("subcategory")

  // Category-based assignment
  var mapping = {
    network: "Network Support",
    hardware: "Desktop Support",
    "software-email": "Email Support",
    "software-erp": "ERP Support",
    database: "Database Admins",
  }

  var key = category
  if (subcategory) {
    key = category + "-" + subcategory
  }

  var groupName = mapping[key] || mapping[category] || "Service Desk"

  var group = new GlideRecord("sys_user_group")
  if (group.get("name", groupName)) {
    return group.getUniqueValue()
  }

  return null
}

Reassignment with Tracking

// Track reassignments (ES5 ONLY!)
// Business Rule: before, update, incident

;(function executeRule(current, previous) {
  // Check if assignment group changed
  if (current.assignment_group.changes()) {
    // Increment reassignment count
    var count = parseInt(current.getValue("reassignment_count"), 10) || 0
    current.reassignment_count = count + 1

    // Add work note
    current.work_notes =
      "Reassigned from " +
      previous.assignment_group.getDisplayValue() +
      " to " +
      current.assignment_group.getDisplayValue()

    // Alert if excessive reassignments
    if (count >= 3) {
      gs.eventQueue("incident.excessive.reassignments", current, count.toString(), "")
    }
  }
})(current, previous)

Major Incident Management (ES5)

Declare Major Incident

// Declare major incident (ES5 ONLY!)
function declareMajorIncident(incidentSysId, reason) {
  var incident = new GlideRecord("incident")
  if (!incident.get(incidentSysId)) {
    return false
  }

  // Set major incident flag
  incident.setValue("major_incident_state", "confirmed")
  incident.setValue("priority", 1)

  // Set major incident fields
  incident.setValue("u_major_incident_start", new GlideDateTime())
  incident.setValue("u_major_incident_reason", reason)

  // Assign to Major Incident team
  var miTeam = new GlideRecord("sys_user_group")
  if (miTeam.get("name", "Major Incident Team")) {
    incident.setValue("assignment_group", miTeam.getUniqueValue())
  }

  // Add work note
  incident.work_notes = "MAJOR INCIDENT DECLARED\nReason: " + reason

  incident.update()

  // Trigger notifications
  gs.eventQueue("incident.major.declared", incident, "", "")

  // Create bridge call record
  createBridgeCall(incident)

  return true
}

function createBridgeCall(incident) {
  var bridge = new GlideRecord("u_bridge_call")
  bridge.initialize()
  bridge.setValue("u_incident", incident.getUniqueValue())
  bridge.setValue("u_dial_in", "1-800-555-0123")
  bridge.setValue("u_pin", generatePin())
  bridge.setValue("u_start_time", new GlideDateTime())
  bridge.insert()
}

Major Incident Communication

// Send major incident update (ES5 ONLY!)
function sendMajorIncidentUpdate(incidentSysId, updateText, recipientGroups) {
  var incident = new GlideRecord("incident")
  if (!incident.get(incidentSysId)) {
    return
  }

  // Add to work notes
  incident.work_notes = "MAJOR INCIDENT UPDATE:\n" + updateText
  incident.update()

  // Build recipient list
  var recipients = []
  for (var i = 0; i < recipientGroups.length; i++) {
    var members = getGroupMembers(recipientGroups[i])
    recipients = recipients.concat(members)
  }

  // Send notification
  var eventParams = JSON.stringify({
    update: updateText,
    recipients: recipients,
  })
  gs.eventQueue("incident.major.update", incident, eventParams, "")
}

Incident Escalation (ES5)

Time-Based Escalation

// Escalation script for scheduled job (ES5 ONLY!)
;(function executeScheduledJob() {
  var LOG_PREFIX = "[IncidentEscalation] "

  // Find incidents needing escalation
  var now = new GlideDateTime()

  // P1 not acknowledged in 15 minutes
  escalateUnacknowledged("1", 15)

  // P2 not acknowledged in 30 minutes
  escalateUnacknowledged("2", 30)

  // P1 not resolved in 4 hours
  escalateUnresolved("1", 240)

  // P2 not resolved in 8 hours
  escalateUnresolved("2", 480)

  function escalateUnacknowledged(priority, minutes) {
    var threshold = new GlideDateTime()
    threshold.addSeconds(-minutes * 60)

    var gr = new GlideRecord("incident")
    gr.addQuery("priority", priority)
    gr.addQuery("state", 1) // New
    gr.addQuery("sys_created_on", "<", threshold)
    gr.addNullQuery("assigned_to")
    gr.query()

    while (gr.next()) {
      gs.info(LOG_PREFIX + "Escalating unacknowledged P" + priority + ": " + gr.number)
      gr.escalation = 1
      gr.work_notes = "Auto-escalated: Not acknowledged within " + minutes + " minutes"
      gr.update()
      gs.eventQueue("incident.escalation.unacknowledged", gr, priority, "")
    }
  }

  function escalateUnresolved(priority, minutes) {
    var threshold = new GlideDateTime()
    threshold.addSeconds(-minutes * 60)

    var gr = new GlideRecord("incident")
    gr.addQuery("priority", priority)
    gr.addQuery("state", "IN", "1,2") // New or In Progress
    gr.addQuery("sys_created_on", "<", threshold)
    gr.query()

    while (gr.next()) {
      var currentEsc = parseInt(gr.getValue("escalation"), 10) || 0
      if (currentEsc < 3) {
        gr.escalation = currentEsc + 1
        gr.work_notes = "Auto-escalated: Not resolved within target time"
        gr.update()
        notifyNextLevel(gr)
      }
    }
  }

  function notifyNextLevel(incident) {
    var group = incident.assignment_group.getRefRecord()
    if (group.manager) {
      gs.eventQueue("incident.escalation.manager", incident, group.manager, "")
    }
  }
})()

Incident Resolution (ES5)

Resolve Incident

// Resolve incident with validation (ES5 ONLY!)
function resolveIncident(incidentSysId, resolution) {
  var incident = new GlideRecord("incident")
  if (!incident.get(incidentSysId)) {
    return { success: false, message: "Incident not found" }
  }

  // Validate state transition
  var currentState = incident.getValue("state")
  if (currentState === "6" || currentState === "7") {
    return { success: false, message: "Incident already resolved/​closed" }
  }

  // Validate resolution fields
  if (!resolution.code) {
    return { success: false, message: "Resolution code is required" }
  }
  if (!resolution.notes) {
    return { success: false, message: "Resolution notes are required" }
  }

  // Update incident
  incident.setValue("state", 6) // Resolved
  incident.setValue("resolution_code", resolution.code)
  incident.setValue("close_notes", resolution.notes)
  incident.setValue("resolved_at", new GlideDateTime())
  incident.setValue("resolved_by", gs.getUserID())

  // Link to problem/​known error if provided
  if (resolution.problem) {
    incident.setValue("problem_id", resolution.problem)
  }
  if (resolution.knowledge) {
    incident.setValue("u_resolution_article", resolution.knowledge)
  }

  incident.update()

  // Notify caller
  gs.eventQueue("incident.resolved", incident, "", "")

  return {
    success: true,
    message: "Incident resolved",
    number: incident.getValue("number"),
  }
}

Incident Metrics (ES5)

Calculate MTTR

// Calculate Mean Time to Resolve (ES5 ONLY!)
function calculateMTTR(startDate, endDate, filters) {
  var ga = new GlideAggregate("incident")
  ga.addQuery("resolved_at", ">=", startDate)
  ga.addQuery("resolved_at", "<=", endDate)
  ga.addQuery("state", "IN", "6,7")

  // Apply optional filters
  if (filters.priority) {
    ga.addQuery("priority", filters.priority)
  }
  if (filters.category) {
    ga.addQuery("category", filters.category)
  }

  ga.addAggregate("AVG", "calendar_duration")
  ga.addAggregate("COUNT")
  ga.query()

  if (ga.next()) {
    var avgDuration = ga.getAggregate("AVG", "calendar_duration")
    var count = ga.getAggregate("COUNT")

    // Convert to hours
    var durationObj = new GlideDuration(avgDuration)
    var hours = durationObj.getNumericValue() / 3600000

    return {
      mttr_hours: Math.round(hours * 100) / 100,
      incident_count: parseInt(count, 10),
    }
  }

  return { mttr_hours: 0, incident_count: 0 }
}

MCP Tool Integration

Available Tools

ToolPurpose
snow_query_incidentsQuery incident records
snow_query_tableAdvanced incident queries
snow_execute_script_with_outputTest incident scripts
snow_create_business_ruleCreate incident automation

Example Workflow

// 1. Query open P1 incidents
await snow_query_incidents({
  query: "priority=1^active=true",
  fields: "number,short_description,assigned_to,opened_at",
})

// 2. Check incident metrics
await snow_execute_script_with_output({
  script: `
        var stats = calculateMTTR(gs.beginningOfThisMonth(), gs.endOfThisMonth(), {});
        gs.info('MTTR: ' + stats.mttr_hours + ' hours');
    `,
})

// 3. Find unassigned incidents
await snow_query_table({
  table: "incident",
  query: "active=true^assigned_toISEMPTY",
  fields: "number,short_description,priority,assignment_group",
})

Best Practices

  1. Clear Classification - Proper category/​subcategory
  2. Impact Assessment - Accurate impact/​urgency
  3. Assignment Rules - Automated routing
  4. Escalation Paths - Defined procedures
  5. Communication - Regular updates
  6. Resolution Codes - Consistent categorization
  7. Knowledge Linking - Link to KB articles
  8. ES5 Only - No modern JavaScript syntax

More skills from groeimetai

reporting-dashboards logo
groeimetai/snow-flow

reporting-dashboards

Build ServiceNow reports (list/bar/pie/line/pivot/single-score) on sys_report, sys_dashboard layouts with widget placement, scheduled report delivery, and drill-down configuration.

78 0
View
rest-integration logo
groeimetai/snow-flow

rest-integration

Make outbound REST calls from ServiceNow with sn_ws.RESTMessageV2 — basic/bearer/OAuth/API-key auth, error handling by status code, response parsing, sys_rest_message records, and retry with exponential backoff.

78 0
View
mcp-tool-discovery logo
groeimetai/snow-flow

mcp-tool-discovery

Use tool_search to discover and enable lazy-loaded Serac MCP tools (snow_*, jira_*, github_*, etc). Explains naming conventions, search strategies, and always-available activity tools.

78 0
View
atf-testing logo
groeimetai/snow-flow

atf-testing

Build ServiceNow Automated Test Framework tests and suites — impersonation, form steps, assertions, server-side script steps, test parameters, and execution via snow_create_atf_test / snow_execute_atf_test.

78 0
View
import-export logo
groeimetai/snow-flow

import-export

Move data in and out of ServiceNow — CSV parsing into import sets, GlideImportSetTransformer runs, CSV/JSON/XML exports, scheduled data sources, bulk update and deleteMultiple safety patterns.

78 0
View
discovery-patterns logo
groeimetai/snow-flow

discovery-patterns

Configure ServiceNow Discovery — schedules, IP ranges, credential affinities, MID Server assignment, custom probes/sensors, identification rules, and run-status monitoring on discovery_* tables.

78 0
View
csm-patterns logo
groeimetai/snow-flow

csm-patterns

Build ServiceNow Customer Service Management — customer_account, customer_contact, sn_customerservice_case routing, service entitlements with usage decrement, and Customer Portal case submission widgets.

78 0
View
data-policies logo
groeimetai/snow-flow

data-policies

Manage ServiceNow dictionary (sys_dictionary), table/field creation, choice lists, dictionary overrides, and sys_data_policy2 rules that enforce mandatory/read-only/visible field behavior on the data layer.

78 0
View
mobile-development logo
groeimetai/snow-flow

mobile-development

Configure ServiceNow Mobile (Now Mobile/Agent) — sys_sg_mobile_app screens, card builders, push notifications, offline sync rules, mobile actions for barcode/GPS, and offline-queue change processing.

78 0
View
email-notifications logo
groeimetai/snow-flow

email-notifications

Create ServiceNow sysevent_email_action notifications — templates with substitution variables, mail scripts for dynamic content/recipients/attachments, custom events, weights, and digest configuration.

78 0
View
es5-compliance logo
groeimetai/snow-flow

es5-compliance

Enforce ES5-only syntax for ServiceNow server-side scripts (Rhino engine) — convert const/let, arrow functions, template literals, destructuring, for-of, and async/await to ES5 equivalents.

78 0
View
change-management logo
groeimetai/snow-flow

change-management

Create and transition ServiceNow change requests (normal/standard/emergency), change tasks, affected CIs, approval routing, CAB scheduling, and conflict detection across maintenance windows.

78 0
View

Popular AI tools

Kaiber logo
Video

Kaiber

Generate, edit, and beat-sync AI video with leading models in one workspace.

Paid
View
Vimcal logo
Productivity

Vimcal

The world's fastest calendar for remote work

Free
View

Transform Your Design with AI Designer by ImgCreator.ai

Freemium
View
Akool AI logo
Content & writing

Akool AI

Revolutionizing Video Production with AI-Powered Creativity

Paid
View

Extend an image past the frame and let AI fill the new aspect ratio.

Freemium
View
StarByFace logo
Security

StarByFace

Discover your celebrity doppelgänger with StarByFace!

Free
View
C

ChainClarity explains 700+ crypto whitepapers in plain English, with layered summaries, comparisons, research tools, alerts, and a $4.99 Pro plan.

Freemium
View
Opus Clip logo
Coding & apps

Opus Clip

Opus.ai: Revolutionize Your Web Experience

Free
View