How to Create a Change Request Using a Script






Mastering Change: How to Create Change Requests Using Script in ServiceNow


Mastering Change: How to Create Change Requests Using Script in ServiceNow

In the fast-paced world of IT Service Management (ITSM), efficiency is king. While clicking through forms is part of daily life, there often comes a point where manual processes become a bottleneck. This is especially true for tasks that are repetitive, conditional, or need to happen in response to other events within your ServiceNow ecosystem. One such powerful automation is the ability to create Change Requests programmatically using scripts.

Whether you’re a seasoned ServiceNow developer looking to optimize workflows, or an aspiring administrator eager to deepen your understanding, scripting Change Requests is a crucial skill. It’s about more than just automation; it’s about building a more robust, responsive, and reliable IT environment. Let’s dive in and demystify the magic behind creating Change Requests with code.

The “Why” Behind Scripted Change Requests: From Incident to Innovation

Before we jump into the “how,” let’s understand the “why.” Why would you ever want to create a Change Request (CR) with a script instead of just using the form? The answer lies in the interconnected nature of ITIL processes and the drive for automation.

The ITIL Triad: Incident, Problem, and Change Management

Think about the typical lifecycle of an IT issue. It often starts with an Incident. Someone faces a problem – their laptop isn’t connecting to Wi-Fi, an application crashes, or a server goes down. This generates an Incident ticket.

Now, if that same Wi-Fi issue keeps popping up for multiple users, or that application keeps crashing repeatedly, we’re no longer just dealing with a one-off Incident. We’re looking at a deeper root cause. That’s when we transition to Problem Management. A Problem record is created to investigate and find the underlying reason for recurring Incidents.

Sometimes, the investigation of a Problem (or even a single critical Incident) reveals that the root cause requires a modification to an existing service, system, or software. This could be anything from a software patch, a configuration update, a new hardware installation, or even a change in a business process. This is precisely where Change Management comes into play. As a support engineer might feel, if there should be some change in the software or infrastructure, they will raise a Change Request from that Incident or Problem (Ref 29, 22).

This is a classic scenario where scripting shines. Imagine a business rule that, under certain conditions (e.g., an Incident impacting a critical service reaches a specific state, or a Problem is confirmed to require a code fix), automatically generates a pre-filled Change Request. This saves time, reduces human error, and ensures adherence to process.

Understanding the Building Blocks: GlideRecord and Task Tables

At the heart of almost all record manipulation in ServiceNow scripting lies the GlideRecord API. It’s your primary tool for interacting with the database, allowing you to query, insert, update, and delete records (Ref 25, 41).

The Power of GlideRecord

Think of GlideRecord as your direct line to the database tables. When you want to create a new record, modify an existing one, or fetch data, GlideRecord is your go-to. It’s incredibly versatile and fundamental to almost any server-side script you’ll write in ServiceNow.

What’s a Task Table?

In ServiceNow, many core ITIL processes revolve around a foundational table called Task. Incident, Problem, and Change Request are all examples of tables that “extend” the Task table (Ref 32). This means they inherit all the fields and behaviors of the Task table, like ‘Number’, ‘Short Description’, ‘Description’, ‘State’, ‘Assigned To’, ‘Assignment Group’, etc., and then add their own specific fields.

When you extend a table, the system fields (like sys_id, sys_created_on, sys_updated_by) aren’t duplicated in the child table. They are inherited from the parent. The child table also gets a special field called ‘Class’ which indicates its type (e.g., Incident, Problem, Change Request). Interestingly, even if a table extends multiple other tables (which is rare but possible in complex hierarchies), it will only have one ‘Class’ field – it doesn’t create a new one for each parent (Ref 35).

This inheritance model makes scripting more efficient and consistent. If you know how to manipulate a Task record, you’re halfway to manipulating an Incident, Problem, or Change Request.

Crafting Your First Change Request Script

Alright, let’s get our hands dirty with some code! The core process for creating a Change Request (or any record, really) using a script involves these steps:

  1. Instantiate a new GlideRecord object for the target table.
  2. Initialize the new record.
  3. Set the values for the desired fields.
  4. Insert the record into the database.

Here’s the breakdown, inspired by the provided example (Ref 25):

var gr = new GlideRecord('change_request'); // 1. Instantiate GlideRecord for the 'change_request' table
gr.initialize();                           // 2. Initialize a new, empty record

// 3. Set field values
gr.category = 'inquiry';                   // Setting a string value for 'category'
gr.subcategory = 'antivirus';              // Setting a string value for 'subcategory'

// For reference fields, you MUST use the sys_id of the referenced record.
// If you don't know the sys_id, you'd query for it first.
gr.cmdb_ci = 'affd3c8437201000deeabfc8bcbe5dc3'; // Setting a Configuration Item (CI) by its sys_id
gr.assignment_group = 'a715cd759f2002002920bde8132e7018'; // Setting an Assignment Group by its sys_id

gr.short_description = 'Automated Change Request for System Update'; // Setting a string
gr.description = 'This change request was automatically generated to facilitate a critical system update identified from a recurring incident pattern.'; // Setting a string

// You can set other standard fields inherited from the Task table:
gr.priority = 2; // Example: Critical priority (value depends on your system's priority definitions)
gr.requested_by = gs.getUserID(); // Set the requested_by to the currently logged-in user

// 4. Insert the record
var changeSysId = gr.insert(); // The insert() method returns the sys_id of the newly created record

if (changeSysId) {
    gs.info('Successfully created Change Request: ' + gr.number + ' (sys_id: ' + changeSysId + ')');
    // You can also redirect the user to the new change record if this script is running in a UI action
    // action.setRedirectURL(gr);
} else {
    gs.error('Failed to create Change Request.');
}

Let’s dissect this script line by line:

  • var gr = new GlideRecord('change_request');: This line creates a new GlideRecord object and tells it we want to work with the change_request table.
  • gr.initialize();: This is crucial! It prepares a new, empty record in memory. Without this, you’d be trying to update an existing record (or get an error) rather than creating a new one.
  • gr.fieldName = 'value';: This is how you set the values for the fields on your new Change Request.
    • For simple string or integer fields (like category, short_description, priority), you assign the value directly.
    • Important for Reference Fields (Ref 47): For fields that reference another record (like cmdb_ci which references the Configuration Item table, or assignment_group which references the Group table), you must provide the sys_id of the referenced record. If you try to give it the display name (e.g., ‘Antivirus Server’ for a CI or ‘Network Team’ for an assignment group), it won’t work correctly, and the field will likely be empty. If you want to set a reference field by its display value, you’d use gr.setDisplayValue('field_name', 'Display Value'), but setValue with sys_id is often more robust in background scripts.
  • var changeSysId = gr.insert();: This is the magic moment! This command saves your new record to the database. It returns the sys_id of the newly created record, which can be incredibly useful for logging or for linking this new change to other records.

Taking it Further: Contextual Scripting with `current`

Often, you’ll want to create a Change Request not in isolation, but as a direct result of an action on another record, like an Incident or a Problem. This is where the current object becomes invaluable.

Understanding the `current` Object

The current object is a special GlideRecord object that represents the record on which the current script (e.g., a Business Rule, UI Action, or Workflow script) is running (Ref 46). It allows you to access and modify the values of the fields on that particular form. For instance, if you’re writing a Business Rule on the Incident table, current refers to the Incident record that triggered the rule.

Creating a Change Request from an Incident

Let’s say you have a UI Action on the Incident form that a support engineer can click to “Create Change Request.” Here’s how you might use current to populate the new Change Request with details from the Incident:

// This script would typically run in a UI Action on the Incident table,
// or a Business Rule triggered by an Incident state change.

// 1. Instantiate GlideRecord for the 'change_request' table
var grChange = new GlideRecord('change_request');
grChange.initialize();

// 2. Populate fields from the 'current' Incident record
grChange.short_description = 'Change related to Incident: ' + current.number + ' - ' + current.short_description;
grChange.description = 'This change is being raised in relation to Incident: ' + current.number + '\n' +
                       'Original Incident Description: ' + current.description;

// Link the Change Request back to the original Incident (optional, but good practice)
// 'parent' is a common field on Change Request that can link to a Problem or Incident
grChange.parent = current.sys_id; 

// Inherit important reference fields from the Incident
grChange.assignment_group = current.assignment_group; // Use current.assignment_group (it holds sys_id)
grChange.assigned_to = current.assigned_to;           // Use current.assigned_to (it holds sys_id)
grChange.requested_by = current.caller_id;            // The person who reported the incident
grChange.cmdb_ci = current.cmdb_ci;                   // If the incident has a CI, link it to the change

// Set initial Change-specific fields
grChange.category = 'enhancement'; // Or 'software', 'hardware', 'emergency', etc.
grChange.type = 'standard';      // Normal, Standard, Emergency (check your system's values)
grChange.priority = current.priority; // Can inherit priority from incident or set a new one

// 3. Insert the new Change Request
var newChangeSysId = grChange.insert();

if (newChangeSysId) {
    gs.addInfoMessage('Change Request ' + grChange.number + ' created successfully from Incident ' + current.number);

    // Optional: Update the original incident to link to the new change
    // current.setValue('change_request', newChangeSysId); // Assuming you have a 'change_request' field on Incident
    // current.update(); // Save the incident record
    
    // Redirect to the newly created Change Request (useful for UI Actions)
    action.setRedirectURL(grChange);
} else {
    gs.addErrorMessage('Failed to create Change Request from Incident ' + current.number);
}

Notice how we directly use current.fieldName to pull data from the Incident. For reference fields like assignment_group or cmdb_ci, the current.fieldName already holds the sys_id, so you can directly assign it to the new Change Request’s corresponding reference field.

If you wanted to set a field on the current form itself (e.g., if you had a ‘Related Change’ field on the Incident form that you wanted to populate), you would use current.setValue('field_name', value) or current.setDisplayValue('field_name', 'Display Value') (Ref 47).

Real-World Application & Advanced Scenarios: Robust Automation

Automating Change Request creation goes beyond simple copying. It integrates with your entire ITIL process flow (Ref 56), making it more dynamic and intelligent.

Automating Change from Problem Records

Similar to Incidents, Problems often lead to Changes. A confirmed Problem might automatically trigger a ‘Standard Change’ for a software patch. Your script could live in a Business Rule on the Problem table, triggering when the Problem state changes to ‘Resolved’ or ‘Known Error’.

Conditional Change Creation: When NOT to Create a Change

Not every Incident or Problem warrants an automated Change. You need to build intelligence into your scripts. For example:

  • Check for existing changes: Is there already an active Change Request related to this Incident/Problem?
  • State validation: Only create a Change if the Incident is in a specific state (e.g., ‘Resolved’ pending closure, or ‘Awaiting Change’).
  • Category/CI specific: Only create a Change if the Incident’s category is ‘Software Error’ and affects a critical CI.

Ensuring Data Integrity: Pre-Checks Before Action

Just as you wouldn’t want to close an Incident that still has open tasks associated with it (Ref 27), you might want to implement similar pre-checks before automatically creating a Change or performing any critical action. This ensures data integrity and prevents unintended consequences.

Let’s adapt the concept from Reference 27. Imagine a scenario where you’re trying to resolve a Problem, and your process requires a Change Request to be created first. You might want to ensure that if there are any related *Problem Tasks* that are still open, you prevent the Problem from moving to a state that would trigger an automated Change, or perhaps prevent it from being resolved until the Change is successfully linked.

// Example: A Business Rule on the Problem table, running before update.
// This prevents a Problem from being resolved if it has open tasks.
// (Adaptation of Ref 27 to a Problem context, demonstrating a pre-check)

// Check if the state is changing to 'Resolved' (or whatever triggers your Change creation)
if (current.state.changesTo(4) && current.state != previous.state) { // Assuming 4 is 'Resolved' state value

    var grProblemTask = new GlideRecord('problem_task'); // Check for related problem tasks
    grProblemTask.addQuery('problem', current.sys_id);
    grProblemTask.addQuery('state', '!=', 3); // Assuming 3 is the state value for 'Closed'
    grProblemTask.query();

    if (grProblemTask.hasNext()) {
        gs.addErrorMessage('Cannot resolve this Problem because there are open Problem Tasks associated with it. Please close all tasks first.');
        current.setAbortAction(true); // Prevent the Problem from being saved in the 'Resolved' state
    } else {
        // If no open tasks, proceed with your logic to create the Change Request here
        // (You would put the GlideRecord for Change creation script here)
        gs.info('No open problem tasks. Proceeding with Problem resolution and potential Change creation.');
    }
}

This kind of conditional logic makes your automations robust. Before your script creates a Change, it could check if the source Incident is still ‘Active’, or if a ‘Configuration Item’ is actually populated. Always validate your data before writing it to the database.

Troubleshooting Common Pitfalls

Even the most seasoned developers hit snags. Here are some common issues when scripting Change Requests and how to troubleshoot them:

  1. Change Request Not Created:

    • Missing gr.initialize(): This is a classic! If you forget initialize(), your script might fail silently or try to query/update an existing record instead of creating a new one.
    • Missing gr.insert(): The record won’t be saved without this.
    • Permissions: The user running the script (or the system if it’s a background script/BR) might not have the necessary write permissions to the change_request table or specific fields. Check ACLs.
    • Business Rules: Other Business Rules on the change_request table might be aborting the action (e.g., a “before insert” rule preventing creation if certain conditions aren’t met). Check the system logs for error messages.
  2. Fields Not Populated Correctly:

    • Incorrect Field Names: Double-check the exact database name of the fields. Sometimes, the label is different from the backend name (e.g., ‘Short description’ vs. short_description).
    • Reference Fields: This is the most common culprit. Are you passing the sys_id for reference fields (like cmdb_ci, assignment_group, requested_by)? If you pass a display name (e.g., ‘IT Operations’ instead of ‘a715cd759f2002002920bde8132e7018’), the field will likely remain empty (Ref 47).
    • Choice List Values: For fields like category or type, ensure you are using the correct *value* of the choice list item, not just the label. You can find these in the dictionary entry for the field.
  3. Script Not Running:

    • Business Rule Conditions: If your script is in a Business Rule, check the ‘When’ and ‘Condition’ fields. Is it running at the right time (before/after insert/update) and under the correct circumstances?
    • UI Action Conditions: For UI Actions, ensure the ‘Condition’ script evaluates to true.
    • Errors in Code: Even a small syntax error can prevent a script from running. Use the JavaScript debugger or gs.info()/gs.error() statements generously to trace execution and variable values.
  4. Debugging Tools:

    • gs.log(), gs.info(), gs.debug(), gs.error(): These are your best friends. Use them to print messages and variable values to the System Log to understand what your script is doing at each step.
    • Script Debugger: For more complex server-side scripts, use the built-in Script Debugger in ServiceNow to step through your code.

Interview Relevance and Mastering the Concept

Understanding how to script Change Requests (and indeed, any record manipulation) is a highly valued skill in the ServiceNow ecosystem. Interviewers frequently probe your knowledge in this area. Here’s how the concepts we covered relate to common interview questions:

  • “How do you create a record in ServiceNow using a script?” (Ref 41): Your detailed explanation of GlideRecord, initialize(), setting fields, and insert() directly answers this.
  • “What is the relationship between Incident, Problem, and Change Management?” (Ref 29): Being able to articulate the flow from an Incident leading to a Problem, and then to a Change Request, demonstrates your grasp of ITIL fundamentals and how automation supports them.
  • “Can you create a Change Request from an Incident?” (Ref 22): Not only can you say “Yes,” but you can also explain *how* using a script, referencing the current object and field mapping.
  • “What is GlideRecord?” (Ref 25): You now have a solid understanding to explain its purpose and core methods.
  • “What is the current object?” (Ref 46): You can explain its context-specific nature and how it’s used to interact with the record initiating the script.
  • “How do you set field values on the current form / for a new record?” (Ref 47): You can differentiate between setting simple values and the critical importance of using sys_id for reference fields, and when to use setValue vs. setDisplayValue.
  • “What happens when you extend a table?” (Ref 35): This shows a deeper understanding of the ServiceNow data model.
  • “Give examples of task tables.” (Ref 32): Knowing that Incident, Problem, and Change Request extend Task is fundamental.
  • “How would you prevent an Incident from closing if it has open tasks?” (Ref 27): This specific example tests your ability to write validation logic using GlideRecord queries and current.setAbortAction(true), a crucial skill for building robust automations.

By practicing these concepts, you’re not just learning to code; you’re learning to think like a ServiceNow architect, capable of building intelligent, automated solutions.

Conclusion

Scripting Change Requests in ServiceNow is a powerful capability that allows you to move beyond manual data entry and embrace true automation. From automatically initiating a Change after a Problem is confirmed to pre-populating essential fields based on an originating Incident, the possibilities are vast.

By leveraging GlideRecord, understanding table extension, and thoughtfully using the current object, you can craft intelligent scripts that streamline your ITIL processes, reduce human error, and free up your teams to focus on more strategic initiatives. Remember, robust automation isn’t just about making things happen; it’s about making them happen reliably, with built-in checks and balances. So, get scripting, experiment, and empower your ServiceNow instance to work smarter, not harder!


Scroll to Top