Working with Incident Records: Best Practices for Effective Management

Mastering Incident Records: Your Guide to Keeping Services Smooth and Sanity Intact

Ever felt the sudden dread when a critical system grinds to a halt? That’s where incident records step in. Dive deep into the heart of IT service management with this comprehensive guide to incident records, their siblings, and how to wield them like a pro.

In the bustling world of IT, things inevitably go wrong. Networks hiccup, applications crash, and users, well, they just want their stuff to work. This isn’t just about fixing things; it’s about a systematic approach to restoring normalcy, learning from outages, and preventing future disruptions. At the core of this strategy lies the humble yet mighty Incident Record.

Think of an incident record as the digital equivalent of a 911 call for your IT services. It’s the first step in addressing a problem, and understanding how to effectively create, manage, and relate these records is crucial for any IT professional. Whether you’re a fresh-faced support engineer or a seasoned ServiceNow developer, this article will walk you through the nuances of incident management, problem identification, change enablement, and the powerful scripting that ties it all together.

The ABCs of Service Disruption: Incident vs. Problem

Before we dive into the nitty-gritty, let’s clear up some fundamental definitions. These might seem basic, but they’re the bedrock of effective IT Service Management (ITSM) and a common area for confusion.

What Exactly is an Incident?

Imagine Bob in accounting trying to send out the quarterly report, and suddenly, his email client just… stops. He can’t send, he can’t receive. This “sudden interruption in service” is the quintessential definition of an incident. It’s an unplanned interruption to an IT service or a reduction in the quality of an IT service. The goal of incident management is to restore normal service operation as quickly as possible and minimize the adverse impact on business operations.

When Bob contacts the IT help desk, a support engineer will create an incident record to document the issue, track its resolution, and communicate with Bob until his email is back up and running. It’s about getting things working again, ASAP.

And What About a Problem?

Now, let’s say Bob’s email stops working every Tuesday morning. Or perhaps, not just Bob, but a dozen other users across different departments report similar email issues every now and then. This repeated occurrence, or the same issue affecting multiple people, points towards a deeper systemic flaw. This is where a problem comes into play.

A problem is the underlying cause of one or more incidents. While incidents focus on restoring service, problem management aims to identify and eliminate the root cause of those incidents. If multiple incidents are all symptoms of the same core issue, we might create a “parent incident” to link them. This helps consolidate efforts and ensures that when the root cause (the problem) is solved, all related symptomatic incidents are also addressed, often as “child incidents” that close when the parent is resolved.

Interview Insight: This distinction is a classic ITIL interview question. Be ready to explain it with clear examples!

The Interconnected Web: Incident, Problem, and Change Management

These three processes aren’t isolated islands; they’re deeply intertwined, forming a continuous improvement loop for your IT services.

From Incident to Problem: “Here We Go Again!”

It’s a common scenario: you fix an incident, only for it to resurface a week later. Or maybe it’s not the exact same user, but the symptoms are eerily familiar across different users. When an issue repeatedly occurs, that’s your cue to shift gears. You can, and should, create a problem record directly from an incident. This signals to the team that this isn’t just a fire to put out; it’s a structural weakness that needs investigating and fixing.

From Incident to Change: “Let’s Make This Permanent”

Sometimes, resolving an incident reveals that the existing system, software, or infrastructure simply isn’t up to snuff. Perhaps the support engineer discovers a bug, an architectural flaw, or a missing feature that, if addressed, would prevent a whole class of incidents. In such cases, they might feel that “there should be some change in the software” or infrastructure. This is where you arise a change request from that incident.

A change request is a formal proposal to modify an IT service, system, or configuration item. It ensures that changes are planned, tested, and implemented in a controlled manner, minimizing disruption and risk. This completes the cycle: an incident exposes a weakness, a problem identifies the root cause, and a change implements the solution.

Interview Insight: Being able to articulate the relationship between Incident, Problem, and Change Management demonstrates a holistic understanding of ITSM and ITIL principles.

The Power of Automation: Creating Records with Script

While users can create incidents through forms, emails, or even record producers, as a developer or administrator, you’ll often need to programmatically create or manipulate these records. Enter GlideRecord – your best friend for database interactions in ServiceNow.

You can create records in ServiceNow in multiple ways: through forms, record producers, email, importing excel sheets, or even from external systems. But for automation and integration, scripting is king.

Creating an Incident Record Using Script (GlideRecord)

The `GlideRecord` API is how you interact with the database tables. It allows you to query, insert, update, and delete records.

var gr = new GlideRecord('incident');
gr.initialize(); // Prepares a new, empty record for insertion
gr.caller_id = '86826bf03710200044e0bfc8bcbe5d94'; // Sys_id of the user
gr.category = 'inquiry';
gr.subcategory = 'antivirus';
gr.cmdb_ci = 'affd3c8437201000deeabfc8bcbe5dc3'; // Sys_id of the Configuration Item
gr.short_description = 'Automated test incident record using script';
gr.description = 'This incident was generated via a server-side script for testing purposes.';
gr.assignment_group = 'a715cd759f2002002920bde8132e7018'; // Sys_id of the assignment group
gr.insert(); // Commits the new record to the database
gs.info("Incident " + gr.number + " created successfully!"); // Optional: log the new incident number

Breakdown:

  • new GlideRecord('incident'): Creates an object representing the ‘incident’ table.
  • gr.initialize(): This is crucial! It sets up a new record for insertion, populating default values where applicable.
  • gr.fieldName = 'value': Assigns values to fields. For reference fields (like `caller_id`, `cmdb_ci`, `assignment_group`), you generally need to provide the sys_id of the referenced record.
  • gr.insert(): Saves the new record to the database.

Creating a Problem Record Using Script

The process is almost identical, just targeting the `problem` table:

var gr = new GlideRecord('problem');
gr.initialize();
gr.caller_id = '86826bf03710200044e0bfc8bcbe5d94'; // Though problems often don't have a direct 'caller', it might be populated from a related incident.
gr.category = 'inquiry';
gr.subcategory = 'antivirus';
gr.cmdb_ci = 'affd3c8437201000deeabfc8bcbe5dc3';
gr.short_description = 'Automated test problem record using script';
gr.description = 'Root cause analysis required for repeated antivirus issues.';
gr.assignment_group = 'a715cd759f2002002920bde8132e7018';
gr.insert();
gs.info("Problem " + gr.number + " created successfully!");

Creating a Change Request Using Script

And for a change request, we target the `change_request` table:

var gr = new GlideRecord('change_request');
gr.initialize();
// Note: Change requests typically don't have a 'caller_id' field directly, but might have 'requested_by' or 'requested_for'.
// We are omitting 'caller_id' here as per the example.
gr.category = 'software'; // Example category for change
gr.subcategory = 'upgrade'; // Example subcategory
gr.cmdb_ci = 'affd3c8437201000deeabfc8bcbe5dc3';
gr.short_description = 'Automated test change request for software update';
gr.description = 'Propose a software patch to address recurrent incident patterns.';
gr.assignment_group = 'a715cd759f2002002920bde8132e7018';
gr.insert();
gs.info("Change Request " + gr.number + " created successfully!");

Troubleshooting Tip: If your script isn’t creating records or fields are blank, double-check:

  • Are you using the correct table name?
  • Are the field names (`caller_id`, `short_description`) spelled exactly right?
  • For reference fields, are you providing a valid `sys_id`? An incorrect `sys_id` will often result in a blank field.
  • Are there any mandatory fields you’ve missed? The `insert()` operation will fail silently or throw an error if mandatory fields are not populated.

Interview Relevance: `GlideRecord` is the bread and butter of server-side scripting in ServiceNow. Expect questions on how to create, query, update, and delete records programmatically.

Automating Lifecycle Management: Business Rules in Action

ServiceNow truly shines when you automate repetitive tasks and enforce business logic. Business Rules are server-side scripts that run when a record is displayed, inserted, updated, or deleted. They are perfect for managing the relationships and lifecycle of incident records.

Closing Child Incidents When Parent Closes

A smart way to manage related incidents is to ensure that when the “parent” issue is resolved, all associated “child” issues automatically follow suit. This prevents stale records and provides a complete picture of the resolution.

Logic: Write an ‘after’ Business Rule on the `incident` table.

When: After
Update: true
Condition: current.state.changesTo(7) && current.parent.nil()

// Script:
if (current.state == 7 && current.parent.nil()) { // Ensure it's the parent incident changing to Closed (state 7)
    // GlideRecord to find child incidents
    var grChild = new GlideRecord('incident');
    grChild.addQuery('parent', current.sys_id); // Query where the parent field is the current incident's sys_id
    grChild.addQuery('state', '!=', 7); // Only close children that are not already closed
    grChild.query();
    while (grChild.next()) {
        grChild.state = 7; // Set the state to Closed (assuming 7 is 'Closed')
        grChild.update(); // Update the child incident
        gs.info("Closed child incident " + grChild.number + " due to parent " + current.number + " closure.");
    }
}

Explanation: This script triggers *after* an incident is updated. It checks if the `state` field has *just changed to* ‘Closed’ (state value 7) and if the current incident itself is a parent (meaning its `parent` field is empty or `nil()`). If both are true, it then finds all other incidents whose `parent` field points to the `sys_id` of the current incident and sets their state to ‘Closed’.

Preventing Closure with Open Tasks

You wouldn’t want an incident, problem, or change request to be marked “closed” if there are still active tasks associated with it, right? This ensures that all work is completed before the main record is closed.

Logic: Write a ‘before’ Business Rule on the `incident`, `problem`, or `change_request` table.

When: Before
Update: true
Condition: current.state.changesTo(7) // Assuming state 7 is 'Closed'

// Script:
if (current.state == 7) { // Check if the current record is being set to Closed
    var taskTable;
    // Determine the correct task table based on the current table
    if (current.getTableName() == 'incident') {
        taskTable = 'incident_task';
    } else if (current.getTableName() == 'problem') {
        taskTable = 'problem_task';
    } else if (current.getTableName() == 'change_request') {
        taskTable = 'change_task';
    }

    if (taskTable) {
        var grTask = new GlideRecord(taskTable);
        grTask.addQuery('parent', current.sys_id); // 'parent' is often the field linking tasks to their parent record
        grTask.addQuery('state', '!=', 3); // Assuming 3 is the state value for 'Closed' for tasks
        grTask.query();

        if (grTask.hasNext()) { // If any open tasks are found
            gs.addErrorMessage('Cannot close this ' + current.getTableName() + ' because there are open tasks. Please close all associated tasks first.');
            current.setAbortAction(true); // Prevents the current record from being saved
        }
    }
}

Explanation: This ‘before’ Business Rule runs *before* the record is saved. If a user tries to close the incident/problem/change (state 7), the script checks for any associated tasks that are *not* in a ‘Closed’ state (state 3). If it finds any, it displays an error message to the user (`gs.addErrorMessage`) and, critically, uses `current.setAbortAction(true)` to prevent the record from being saved in the ‘Closed’ state. This is a common and powerful technique for enforcing data integrity.

Interview Relevance: `setAbortAction()` is a crucial function for validation in Business Rules.

Closing Associated Incidents When Problem Closes

Once the root cause (the problem) is resolved, it’s good practice to close all incidents that were caused by that problem.

Logic: Write an ‘after’ Business Rule on the `problem` table.

When: After
Update: true
Condition: current.state.changesTo(7) // Assuming state 7 is 'Closed'

// Script:
if (current.state == 7) { // If the problem is now closed
    // GlideRecord to find incidents associated with the problem
    var grIncident = new GlideRecord('incident');
    grIncident.addQuery('problem_id', current.sys_id); // Query incidents where problem_id points to current problem
    grIncident.addQuery('state', '!=', 7); // Only close incidents that are not already closed
    grIncident.query();
    while (grIncident.next()) {
        grIncident.state = 7; // Set the incident state to Closed
        grIncident.update(); // Update the incident
        gs.info("Closed incident " + grIncident.number + " due to problem " + current.number + " closure.");
    }
}

Explanation: Similar to the parent-child incident closure, this rule triggers after a problem is updated to ‘Closed’. It then finds all incidents that have their `problem_id` field linked to the current problem and updates their state to ‘Closed’.

Building Blocks: The Task Table and Relationships

The Mighty Task Table

You might have noticed that Incident, Problem, and Change Request records all share many common fields: Short Description, Description, State, Assignment Group, etc. This isn’t a coincidence! They all extend the core ‘Task’ table (`task`).

The `task` table is a foundational table in ServiceNow. It provides a common set of fields and functionalities for any record that represents “work to be done.” This inheritance model is a key aspect of ServiceNow’s architecture, promoting consistency and reusability. Examples of tables extending `task` include:

  • incident
  • problem
  • change_request
  • sc_req_item (Service Catalog Request Item)
  • sc_task (Service Catalog Task)

Interview Relevance: Understanding table inheritance from the `task` table is fundamental to comprehending the ServiceNow data model.

Understanding Table Relationships

How records relate to each other is critical for a well-structured system:

  • One-to-Many Relationship: A single record in one table can be associated with multiple records in another table, but each record in the second table is associated with only one record in the first.
    • Example: Users and Incidents. One user (e.g., Bob) can report multiple incidents, but each incident is typically reported by only one user.
  • Many-to-Many Relationship: A record in one table can be associated with multiple records in another table, and vice-versa.
    • Example: Incidents and Groups. An incident might involve multiple assignment groups (e.g., Network and Server teams), and a single group can be associated with many incidents. (Often managed through an intermediary “junction” table).

Fine-Tuning the User Experience: Form and Field Manipulation

A well-designed form makes all the difference for user adoption and data quality. ServiceNow offers a multitude of ways to control how fields behave.

Making Fields Mandatory or Read-Only

This is a common requirement to ensure data quality and guide users. You have several tools at your disposal:

  1. Dictionary Properties: The most basic. Edit the field’s dictionary entry and check ‘Mandatory’ or ‘Read only’. This applies globally to the table.
  2. Dictionary Overrides: If a field is inherited from a parent table (like `task`), you can override its dictionary properties (e.g., make it mandatory) specifically for a child table (e.g., `incident`).
  3. UI Policies: Client-side logic to dynamically change field behavior (mandatory, read-only, visible) based on conditions on the form.
  4. Data Policies: Similar to UI Policies but enforce rules at the database level, applying to all data inputs (forms, imports, web services). They can run on both client and server sides.
  5. Client Scripts (`g_form.setMandatory()`): For more complex client-side logic where UI Policies might be insufficient.

Interview Relevance: Knowing all five methods and *when* to use each is a sign of a strong ServiceNow developer.

Setting Default Values on Fields

To streamline form completion, you can set default values for fields that often have the same starting point. This can be done directly in the field’s dictionary entry (Default value field) or via a Client Script (onLoad) or Business Rule (before insert).

The `current` Object: Your Server-Side Companion

When you’re scripting on the server side (like in Business Rules), the `current` object is your gateway to the record currently being processed. It’s used to “set and get the values on the form at the server side.”

Setting Field Values on the Current Form (Server-Side)

When using `current` in a Business Rule:

  • current.setValue('field_name', value);: The most common way. For reference type fields, you must provide the sys_id of the referenced record.
  • current.setDisplayValue('field_name', value);: This is useful for reference fields when you have the display name (e.g., “IT Operations”) but not the sys_id. ServiceNow will try to resolve the sys_id from the display value. Use with caution in scripts, as display values aren’t always unique.

Troubleshooting: If `current.setValue()` isn’t working for a reference field, confirm you’re passing a valid `sys_id`. If you’re using `setDisplayValue()` and it’s not working, ensure the display value is an exact match for an existing record.

Reference Qualifiers: Filtering the Choices

Reference qualifiers are powerful tools “used to restrict the data in reference and List type of fields.” They ensure users only see relevant options in dropdowns, preventing selection errors and improving efficiency.

There are three main types:

  1. Simple Reference Qualifier:
    • Description: The most basic. You specify a fixed query string, just like a filter condition.
    • Example: `active=true^company=javascript:gs.getUser().getCompanyID()` to show only active users from the current user’s company in a ‘Caller’ field.
  2. Dynamic Reference Qualifier:
    • Description: Uses a pre-defined “Dynamic Filter Option” that can adapt based on context. These are created once and reused.
    • Example: Displaying only incidents assigned to the current user’s assignment group. You’d create a Dynamic Filter Option like “Is (dynamic) One of My Groups” and apply it.
  3. Advanced Reference Qualifier (JavaScript):
    • Description: Provides maximum flexibility using custom JavaScript code to define complex queries. It’s evaluated server-side.
    • Example: `javascript: ‘assignment_group=’ + current.assignment_group + ‘^priority<3'` to show only incidents assigned to the same group as the current incident, and with a priority less than 3.

Differences Explained:

  • Simple vs. Dynamic: Simple is static or uses basic `javascript:` values. Dynamic uses pre-configured, reusable filter options, which can be less maintenance for complex conditions used repeatedly.
  • Dynamic vs. Advanced: Dynamic is about *reusing* a predefined filter. Advanced is for *unique, highly specific, or very complex* conditions that can’t be covered by simple filters or existing dynamic options. You write the full query logic in JavaScript.
  • Simple vs. Advanced: Simple is a straightforward `field=value` query. Advanced uses JavaScript to construct that query string dynamically, offering far greater control and context awareness.

Interview Relevance: Reference Qualifiers are a frequently tested concept, especially the differences between the types and how to write an advanced one.

Dependent Values: Cascading Choices

Ever picked a “Category” and then watched the “Subcategory” options magically change? That’s dependent values at work. “Dependent values in a dictionary entry… are used to filter the available choices in one field based on the selection made in another field.”

Example (Category/Subcategory):

  1. Define your parent field’s choices (e.g., Category: Hardware, Software, Network).
  2. Go to the dependent field’s dictionary entry (e.g., Subcategory).
  3. Set the ‘Dependent Field’ attribute to ‘Category’.
  4. When creating choices for Subcategory (e.g., Laptop, Desktop, Printer), you’ll specify which ‘Category’ they are dependent on.

Calculated Values

Sometimes a field’s value isn’t directly input but derived from other fields. If you “want to calculate a field value based on other field value using the current object,” you can use a ‘Calculated’ dictionary property. This involves a script that runs server-side to compute the value.

Attributes: Tweaking Field Behavior

Attributes are additional properties added to dictionary entries that change a field’s or table’s behavior in specific ways, often impacting the UI. Examples include:

  • `no_email`: Prevents the field’s content from being included in email notifications.
  • `no_attachment`: Prevents attachments on the associated table/record.
  • `tree_picker`: Changes how reference fields behave, showing a hierarchical picker.

To enable/disable attachments on a form, you’d find the Collection field for that table (the dictionary entry representing the table itself, not a specific column) and add or remove the `no_attachment` attribute.

Dictionary Overrides: Child Table Customizations

We touched on this briefly, but it’s worth highlighting. “Use a dictionary override to allow a field in a child table to have a different value or behavior than the same field in a parent table.” For instance, you could make the `priority` field mandatory on `incident` but optional on `problem`, even though both inherit it from `task`.

You can override properties like default value, mandatory, read-only, choice list, and even reference qualifiers.

User Interface & Data Integrity: UI Policies vs. Data Policies

These two are often confused but serve distinct purposes in controlling form behavior and data quality.

UI Policies: Client-Side Control

UI policies are “used to make a field mandatory, read only, display and to show the related lists at certain condition in the client side.” They are primarily for enhancing the user experience on forms.

  • Global Checkbox: If checked, the UI Policy applies to all views of the form. Uncheck it to specify a particular view.
  • Reverse if False: If checked, the actions (e.g., making a field mandatory) are reversed when the condition is no longer met. If unchecked, the field stays mandatory even if conditions change (less common).
  • On Load Checkbox: If checked, the UI Policy’s conditions and actions are evaluated and applied immediately when the form loads. If unchecked, they only apply when a relevant field on the form changes.
  • Inherit Checkbox: If checked, the UI Policy applies to child tables that extend the current table.
  • Scripting in UI Policy: Yes, you can! Check the “Run scripts” box to write client-side JavaScript that executes when the policy’s conditions are met. This is for more complex UI interactions than simple field properties.

Troubleshooting: UI policies run on the client, so they can be bypassed by other data entry methods. Also, be mindful of the order of execution if you have conflicting policies.

Data Policies: Server-Side Enforcement (and Client Too!)

Data policies are more robust. They are “used to make field mandatory, read only, display at certain condition from all the data sources, and this works at both client and server side.” This means they enforce data integrity regardless of how the data enters the system (form, import, API, script).

  • Converting UI Policy to Data Policy: Yes, you can convert an existing UI Policy into a Data Policy directly from the UI Policy record. This saves time if you realize client-side enforcement isn’t enough.
  • When UI Policy CANNOT be Converted: Not all UI policies are convertible. Specifically, if a UI Policy is controlling:
    • Data visibility (e.g., showing/hiding specific field values based on conditions).
    • Views (e.g., changing the form view).
    • Related lists (e.g., showing/hiding related lists).
    • Client-side scripts.

    These are purely UI/client-side concerns and don’t translate to database-level enforcement.

Interview Relevance: A common and crucial question is the difference between UI Policies and Data Policies, and when to use each. Remember: UI for user experience, Data for data integrity.

Beyond the Basics: Other Helpful Tools

  • Application Menus: These are how users navigate to forms and lists in ServiceNow. You create modules within application menus to make your custom tables and forms accessible.
  • Process Flow: That visual indicator at the top of a form (e.g., New -> Assess -> Implement -> Review -> Close) showing the state of a record. It provides a quick overview of where a process is.
  • Data Lookup Rules: A separate table used to populate field values automatically based on other field values on the form. Think of it as a configurable way to set default values or auto-fill fields without scripting.

Conclusion: The Art of Incident Resolution

Working with incident records in ServiceNow is much more than just logging a problem. It’s an intricate dance of quick fixes, root cause analysis, and preventative changes, all orchestrated through a powerful platform. By mastering GlideRecord for automation, understanding the lifecycle relationships with Problem and Change Management, and using UI and Data Policies for a robust user experience, you become a more effective IT professional.

Remember, every incident is an opportunity to learn, to improve, and to make your IT services more resilient. So, keep honing your skills, embracing automation, and always strive to deliver a seamless experience to your users. Happy incident resolving!

Scroll to Top