incident-management
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
| Table | Purpose |
|---|---|
incident |
Incident records |
incident_task |
Sub-tasks for incidents |
incident_alert |
Related alerts |
problem |
Related 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
| Tool | Purpose |
|---|---|
snow_query_incidents |
Query incident records |
snow_query_table |
Advanced incident queries |
snow_execute_script_with_output |
Test incident scripts |
snow_create_business_rule |
Create 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
- Clear Classification - Proper category/subcategory
- Impact Assessment - Accurate impact/urgency
- Assignment Rules - Automated routing
- Escalation Paths - Defined procedures
- Communication - Regular updates
- Resolution Codes - Consistent categorization
- Knowledge Linking - Link to KB articles
- ES5 Only - No modern JavaScript syntax
More from groeimetai/snow-flow
knowledge-management
This skill should be used when the user asks to "create knowledge article", "KB article", "knowledge base", "knowledge workflow", "article template", "publish article", or any ServiceNow Knowledge Management development.
87reporting-dashboards
This skill should be used when the user asks to "create report", "dashboard", "chart", "visualization", "analytics", "scheduled report", "export data", or any ServiceNow reporting and dashboard development.
77document-management
This skill should be used when the user asks to "attachment", "document", "file upload", "document template", "PDF generation", "document workflow", or any ServiceNow Document Management development.
74predictive-intelligence
This skill should be used when the user asks to "predictive intelligence", "machine learning", "ML", "classification", "similarity", "clustering", "prediction", "AI", or any ServiceNow Predictive Intelligence development.
72vendor-management
This skill should be used when the user asks to "vendor", "supplier", "contract", "procurement", "SLA", "vendor risk", "vendor performance", or any ServiceNow Vendor Management development.
68mcp-tool-discovery
This skill should be used when the user asks about "available tools", "what tools", "how to find tools", "tool search", "MCP servers", "list tools", "discover tools", "which tools", or needs guidance on discovering and using Snow-Flow MCP tools.
68