Mastering ServiceNow: The Real Assignment Group Workflow
In the intricate world of IT Service Management (ITSM), the efficient handling of requests and incidents is paramount. A cornerstone of this efficiency lies in how work is assigned and managed. At the heart of this lies the concept of Assignment Groups in ServiceNow. This article delves deep into the practical aspects of Assignment Groups, from their foundational elements to advanced workflows, drawing from recent ServiceNow versions and best practices. Whether you’re a seasoned ServiceNow administrator, a developer, or an aspiring ITSM professional, understanding Assignment Groups is crucial for optimizing your instance.
Our Journey Through ServiceNow Versions
My experience with ServiceNow spans several major releases, giving me a comprehensive perspective on how functionalities have evolved. I’ve had the opportunity to work extensively with the platform starting from the Rome release, progressing through San Diego, Tokyo, Utah, Vancouver, and currently working with the latest, Washington DC. This evolution has brought about numerous enhancements in user management, group functionalities, and automation capabilities, all of which directly impact how we leverage Assignment Groups effectively.
Understanding the Building Blocks: Users and Groups
Before we dive into workflows, it’s essential to solidify our understanding of the fundamental components that make up ServiceNow’s user and group management.
User and Group Management: Permissions and Best Practices
A common question when setting up ServiceNow is how to manage user permissions. The answer is a resounding yes – we can add permissions to users and groups. In ServiceNow, permissions are primarily managed through Roles. You can assign roles directly to individual users or, more strategically, to groups.
Best Practice: Group-Based Role Assignment
The universally accepted best practice is to assign roles to groups rather than directly to individual users. Why? Imagine an employee joining or leaving your organization. If an employee leaves, you simply remove them from their respective groups. Automatically, all the roles and permissions associated with those groups are stripped away. This drastically simplifies user lifecycle management, reduces the risk of orphaned permissions, and ensures a more secure and auditable system. Manually managing roles for each user is prone to errors and becomes incredibly cumbersome in larger organizations.
Key Tables for User and Group Management
Understanding the underlying database structure is vital for effective scripting and administration.
- User Table: The primary table for storing user information is
sys_user. This is where details like username, first name, last name, email, and more are kept. - Group Table: The table that defines groups is
sys_user_group. This table stores group names, managers, emails, and descriptions. - Group Membership Table: The link between users and groups is managed in the
sys_user_grmembertable. Each record here represents a user being a member of a specific group. - User Role Table: When a role is directly assigned to a user, a record is created in the
sys_user_has_roletable. - Group Role Table: Similarly, when a role is assigned to a group, a record is created in the
sys_group_has_roletable.
Scripting User and Group Operations
While manual creation is straightforward, scripting offers immense power for automation and bulk operations.
Creating User Accounts with Script
Leveraging GlideRecord, creating a user is a common scripting task:
var userGr = new GlideRecord('sys_user');
userGr.initialize();
userGr.username = 'jdoe';
userGr.first_name = 'John';
userGr.last_name = 'Doe';
userGr.email = 'jdoe@example.com';
// Additional fields can be set here as needed
userGr.insert();
gs.info('User jdoe created successfully.');
Creating Groups with Script
Creating a new group follows a similar pattern:
var newGr = new GlideRecord('sys_user_group');
newGr.initialize();
newGr.name = 'IT Support - Level 1';
// The manager field is a reference to a sys_user record
newGr.manager = 'sys_id_of_manager';
newGr.email = 'itsupport_l1@example.com';
newGr.description = 'Handles initial IT support requests.';
newGr.insert();
gs.info('Group IT Support - Level 1 created successfully.');
Adding Permissions (Roles) with Script
Assigning roles is achieved by inserting records into the respective tables.
To a User:
var userRole = new GlideRecord('sys_user_has_role');
userRole.setValue('user', 'sys_id_of_user'); // e.g., '86826bf03710200044e0bfc8bcbe5d94'
userRole.setValue('role', 'sys_id_of_role'); // e.g., '2831a114c611228501d4ea6c309d626d' (e.g., 'itil' role)
userRole.insert();
gs.info('Role assigned to user.');
To a Group:
var grpRole = new GlideRecord('sys_group_has_role');
grpRole.setValue('group', 'sys_id_of_group'); // e.g., '477a05d153013010b846ddeeff7b1225'
grpRole.setValue('role', 'sys_id_of_role'); // e.g., '2831a114c611228501d4ea6c309d626d'
grpRole.insert();
gs.info('Role assigned to group.');
Managing Group Membership with Script
Adding and removing members from groups is a frequent administrative task.
Adding a Group Member:
var grMem = new GlideRecord('sys_user_grmember');
grMem.user = 'sys_id_of_user'; // e.g., '62826bf03710200044e0bfc8bcbe5df1'
grMem.group = 'sys_id_of_group'; // e.g., '477a05d153013010b846ddeeff7b1225'
grMem.insert();
gs.info('User added to group.');
Removing a Group Member:
var grMem = new GlideRecord('sys_user_grmember');
grMem.addQuery('user', 'sys_id_of_user');
grMem.addQuery('group', 'sys_id_of_group');
grMem.query();
if (grMem.next()) {
grMem.deleteRecord();
gs.info('User removed from group.');
} else {
gs.info('User was not found in the specified group.');
}
User Delegation: Ensuring Continuity
User delegation is a powerful feature allowing one user to perform actions on behalf of another. This is indispensable for business continuity, especially during vacations or leaves.
How it Works: A user can delegate their tasks (like approvals, notifications, or assignments) to a colleague. This is configured within the original user’s record by navigating to the ‘Delegates’ related list. Here, you specify the delegate, the date range, and the specific permissions granted.
Interview Relevance: Understanding delegation highlights your grasp of practical ITSM processes and how ServiceNow supports them to maintain operational efficiency.
Checking Group Membership of the Current User
A common scripting requirement is to check if the currently logged-in user belongs to a specific group:
// Replace 'Group Name' with the actual name of the group
if (gs.getUser().isMemberOf('IT Support - Level 1')) {
gs.info('Current user is a member of IT Support - Level 1.');
} else {
gs.info('Current user is NOT a member of IT Support - Level 1.');
}
This simple check is invaluable in client-side scripts (UI Policies, Client Scripts) and server-side scripts (Business Rules, Script Includes) to control visibility, actions, or assignments.
The Core of ITSM: Incident, Problem, and Change
Assignment Groups are most critically utilized within the core ITSM applications: Incident Management, Problem Management, and Change Management. Understanding these processes is key to understanding how Assignment Groups function within them.
What is an Incident?
An incident is a sudden interruption to a service or a reduction in the quality of a service. When an employee faces an issue that prevents them from working effectively, they report it as an incident. The goal of incident management is to restore normal service operation as quickly as possible and minimize the adverse impact on business operations.
What is a Problem?
A problem is the underlying cause of one or more incidents. If the same issue occurs repeatedly for an individual, or if multiple individuals report similar incidents, it signals a potential problem. Problem management aims to identify the root cause of incidents and prevent them from recurring.
Relationship Highlight: If the same issue impacts multiple people concurrently, it’s initially treated as multiple incidents. A parent incident is created, and subsequent identical reports become child incidents. Resolving the parent incident often resolves all its associated children.
What is a Change Request?
A change request is initiated when a modification to an IT service or configuration item is needed. This could be a software update, a hardware replacement, or a new deployment. Change management ensures that changes are implemented in a controlled manner to minimize risk and disruption.
The Interplay: Incident, Problem, and Change Management
These three processes are deeply interconnected and often feed into each other:
- Incident -> Problem: If a recurring incident is identified, a problem record is created to investigate the root cause.
- Incident -> Change: If resolving an incident requires a modification to the IT environment (e.g., a bug fix requires a code deployment), a change request is created.
- Problem -> Change: Once the root cause of a problem is identified, a change request is typically raised to implement the permanent fix.
Troubleshooting Tip: Inconsistent states between incidents, problems, and changes can lead to confusion. Ensure your workflows clearly define when and how these records should be linked.
Scripting ITSM Records and Workflows
Automating the creation and management of these records is a powerful way to streamline operations.
Creating Incident Records with Script
Assignment groups are critical for ensuring incidents are routed correctly.
var gr = new GlideRecord('incident');
gr.initialize();
gr.caller_id = 'sys_id_of_caller'; // e.g., '86826bf03710200044e0bfc8bcbe5d94'
gr.category = 'inquiry';
gr.subcategory = 'antivirus';
gr.cmdb_ci = 'sys_id_of_ci'; // e.g., 'affd3c8437201000deeabfc8bcbe5dc3' (Configuration Item)
gr.short_description = 'Software not responding';
gr.description = 'The application is freezing intermittently.';
gr.assignment_group = 'sys_id_of_assignment_group'; // e.g., 'a715cd759f2002002920bde8132e7018'
gr.insert();
gs.info('Incident created and assigned.');
Creating Problem Records with Script
When creating a problem, linking it to existing incidents can be crucial.
var gr = new GlideRecord('problem');
gr.initialize();
gr.caller_id = 'sys_id_of_caller';
gr.category = 'network';
gr.subcategory = 'connectivity';
gr.cmdb_ci = 'sys_id_of_ci';
gr.short_description = 'Repeated network disconnections';
gr.description = 'Multiple users reporting intermittent network loss.';
gr.assignment_group = 'sys_id_of_assignment_group';
// Optional: Link to a parent incident if known
// gr.work_notes = 'Related incident: ' + current.sys_id;
gr.insert();
gs.info('Problem record created.');
Creating Change Request Records with Script
Assignment groups are also vital for routing change requests to the appropriate teams.
var gr = new GlideRecord('change_request');
gr.initialize();
gr.category = 'normal'; // Example category
gr.subcategory = 'software_upgrade';
gr.cmdb_ci = 'sys_id_of_ci';
gr.short_description = 'Upgrade Application XYZ to version 3.0';
gr.description = 'Plan to upgrade Application XYZ to enhance performance and security.';
gr.assignment_group = 'sys_id_of_assignment_group'; // e.g., 'CAB Approval Group'
gr.insert();
gs.info('Change request created.');
Advanced Workflow Automation with Business Rules
Business Rules are the workhorses of server-side automation in ServiceNow. They allow us to trigger actions based on record inserts, updates, deletions, or queries. Here are some common scenarios involving Assignment Groups and ITSM records.
Scenario 1: Automatically Closing Child Incidents When Parent is Closed
Logic: If a parent incident is closed, all its associated open child incidents should also be closed.
Implementation: An After Business Rule on the incident table.
- When: After
- Update: True
- Condition:
current.state.changesTo(7) && current.parent == ''(Assuming state 7 is ‘Closed’. Adjust state values as per your instance.)
// Business Rule Script
if (current.state == 7 && current.parent == '') {
var grChild = new GlideRecord('incident');
grChild.addQuery('parent', current.sys_id);
grChild.query();
while (grChild.next()) {
// Only close if not already closed
if (grChild.state != 7) {
grChild.state = 7; // Set to Closed
// Optionally add work notes explaining why
grChild.work_notes = 'Automatically closed as parent incident ' + current.number + ' was closed.';
grChild.update();
}
}
gs.info('Child incidents updated to Closed state.');
}
Troubleshooting: Ensure the `current.parent == ”` condition correctly identifies top-level incidents. Verify the state value for ‘Closed’ in your incident state configuration.
Scenario 2: Preventing Incident Closure if Tasks are Open
Logic: An incident cannot be closed if it has any open incident tasks associated with it.
Implementation: A Before Business Rule on the incident table.
- When: Before
- Update: True
- Condition:
current.state.changesTo(7)
// Business Rule Script
// Check for open incident tasks
var grTask = new GlideRecord('incident_task');
grTask.addQuery('incident', current.sys_id);
grTask.addQuery('state', '!=', 3); // Assuming state 3 is 'Closed'. Adjust as needed.
grTask.query();
if (grTask.hasNext()) {
gs.addErrorMessage('Cannot close the incident. There are open incident tasks. Please close all tasks first.');
current.setAbortAction(true); // Prevent the update from happening
}
Interview Relevance: This demonstrates understanding of enforcing business logic and preventing data integrity issues.
Scenario 3: Automatically Closing Associated Incidents When a Problem is Closed
Logic: When a problem is closed, all associated open incidents should also be closed.
Implementation: An After Business Rule on the problem table.
- When: After
- Update: True
- Condition:
current.state.changesTo(7)(Assuming state 7 is ‘Closed’)
// Business Rule Script
if (current.state == 7) {
var grIncident = new GlideRecord('incident');
// Using problem_id to link incidents to the problem
grIncident.addQuery('problem_id', current.sys_id);
grIncident.addQuery('state', '!=', 7); // Only update if not already closed
grIncident.query();
while (grIncident.next()) {
grIncident.state = 7; // Set to Closed
grIncident.work_notes = 'Automatically closed as associated problem ' + current.number + ' was resolved.';
grIncident.update();
}
gs.info('Associated incidents updated to Closed state.');
}
Troubleshooting: Ensure the `problem_id` field is correctly populated when incidents are linked to problems. Verify state values.
Foundational ServiceNow Concepts
Understanding the underlying architecture of ServiceNow is crucial for effective administration and development. This includes knowledge of its table structure and relationship types.
Base Tables and Extensions
ServiceNow employs a hierarchical table structure. Some tables are considered base tables because they are not extended from any other table but are extended by many others.
task: This is a prime example of a base table. It defines common fields and behaviors for all task-based records like Incidents, Problems, and Change Requests.cmdb_ci: The Configuration Item table is another foundational table, serving as the base for all items within the Configuration Management Database (CMDB).
Table Extension: What Happens?
When you extend a table (e.g., extending the task table to create the incident table):
- Fields defined in the parent table (e.g.,
short_description,statefromtask) are automatically inherited by the child table (incident). They don’t get re-created in the child table. - A field named
classis created in the parent table. This field stores the actual table name (e.g., ‘incident’, ‘problem’) for records that extend it. This allows ServiceNow to differentiate between different types of tasks, for instance, when querying thetasktable. - A table can only extend one other table directly. However, a table can inherit fields through multiple levels of extension.
Interview Relevance: This question tests your understanding of ServiceNow’s data model and how inheritance works, which is fundamental to database design.
One-to-One, One-to-Many, and Many-to-Many Relationships
Understanding these relationships is key to designing efficient databases and queries.
- One-to-Many: A user can have many incidents, but each incident is typically assigned to only one user (or assignment group). The link is usually a reference field on the ‘many’ side (e.g.,
caller_idon theincidenttable referencing thesys_usertable). - Many-to-Many: An incident can be associated with multiple assignment groups, and a single assignment group can be responsible for many incidents. This is typically implemented using a separate ‘join’ table (a many-to-many relationship table). In ServiceNow, for example, users can be members of multiple groups, and groups can have multiple users, managed via the
sys_user_grmembertable.
Ways to Create Records in ServiceNow
ServiceNow provides multiple avenues for data entry:
- Forms: The most common method, direct manual entry.
- Record Producers: User-friendly interfaces that simplify creating records from the Service Portal.
- Email: Inbound email actions can create records (e.g., creating an incident from an email).
GlideRecordScripting: As demonstrated throughout this article, for programmatic creation.- Excel Import: Using the Import Set functionality for bulk data loading.
- External Systems: Via REST APIs, SOAP web services, or integration platforms.
Field Configurations and Customizations
ServiceNow offers extensive control over how fields behave and are presented.
Making Fields Mandatory, Read-Only, or Visible
These behaviors can be controlled through several mechanisms:
- Dictionary Properties: Directly on the field’s dictionary entry (e.g., making it mandatory by default).
- Dictionary Overrides: To alter parent table field behavior on a child table.
- UI Policies: Client-side rules for making fields mandatory, read-only, or visible based on conditions on the form load and user interaction.
- Data Policies: Similar to UI Policies but operate on both client and server sides, ensuring data integrity regardless of the entry method.
- Client Scripts: For more complex client-side logic using
g_form.setMandatory('field_name', true);,g_form.setReadOnly('field_name', true);,g_form.setVisible('field_name', true);.
Setting Default Values
This is done in the field’s dictionary entry under the “Default Value” section. It populates the field automatically when a new record is created, ensuring consistency.
Example: Setting a default value of ‘Open’ for the ‘State’ field on a new incident record.
The current Object
The current object is a powerful server-side scripting object that represents the record being processed (e.g., the incident being saved). It’s used to get and set field values.
- Setting Field Values:
current.setValue('field_name', 'value');. For reference fields, you pass thesys_idof the referenced record. - Setting Display Values:
current.setDisplayValue('field_name', 'display_value');. This is useful for setting reference fields using their display text, and ServiceNow will resolve thesys_idbehind the scenes.
Reference Qualifiers: Refining Data Selection
Reference qualifiers are essential for filtering the list of available records in reference fields and multi-select (list) fields, ensuring users select only relevant data.
Types of Reference Qualifiers
- Simple: Uses basic AND/OR conditions directly in the dictionary entry.
Example:
active=true^department=12345Use Case: Filtering users by active status and a specific department.
- Dynamic: Leverages pre-configured “Dynamic Filter Options” (System Definition > Dynamic Filter Options) which can contain more complex logic and be reused.
Example: A dynamic filter option named “My Active Incidents” that queries for incidents where caller_id is current user and state is not closed.
Use Case: Displaying only incidents assigned to the current user’s assignment group or created by the current user.
- Advanced (JavaScript): Uses custom JavaScript code to define highly dynamic and complex filtering logic.
Example:
javascript: 'assignment_group=' + current.assignment_group + '^priority < 3';Use Case: Filtering affected CIs based on other fields in the form, or showing only users from the same company as the caller.
Simple vs. Dynamic: Simple is for static, straightforward filtering. Dynamic is for reusable, context-aware filtering logic.
Dynamic vs. Advanced: Dynamic uses pre-built filter options. Advanced allows complete custom JavaScript control, ideal for highly complex or unique filtering needs.
Troubleshooting: Incorrect sys_ids, typos in field names, or incorrect query logic are common issues with reference qualifiers.
Dependent Values and Calculated Values
Dependent Values
Dependent values create cascaded dropdowns. When a user selects a value in one field (the parent), the options available in another field (the dependent) are filtered accordingly.
Example:
- Parent Field:
Category(e.g., Hardware, Software) - Dependent Field:
Subcategory(e.g., Laptop, Printer for Hardware; OS, Application for Software)
This is configured in the dictionary entry of the dependent field by setting the “Dependent field” attribute and defining choices that link to parent field values.
Calculated Values
When you need a field’s value to be automatically computed based on other fields, you use a calculated value in the field’s dictionary entry. This typically involves a simple script or reference to a function that performs the calculation.
Example: A ‘Total Cost’ field calculated by multiplying ‘Quantity’ and ‘Unit Price’.
Attributes and Dictionary Overrides
Attributes
Attributes are key-value pairs added to field dictionary entries that modify field behavior. They are a powerful tool for customization without scripting.
Common Attributes:
no_email: Prevents email notifications for changes to this field.no_attachment: Disables attachments for this field (useful for specific fields where attachments are not relevant).tree_picker: Enables a tree-like selection interface for reference fields.
Enabling/Disabling Attachments
To disable attachments on a specific field, you would add the no_attachment attribute to its dictionary entry, typically in the “Attributes” field.
Dictionary Overrides
Dictionary overrides are used to customize field behavior in a child table without altering the parent table definition. This is crucial for maintaining a clean and standard parent table while allowing specialized behavior in child tables.
Properties You Can Override:
- Default Value
- Mandatory
- Read-only
- Display
- Max Length
- Attributes
- Reference Specification (e.g., reference qualifier)
- And more…
Example: The default priority for an incident might be ‘4-Low’ (from the task table), but in the incident table, you might override this to have a default of ‘3-Moderate’.
UI Policies vs. Data Policies
These are both powerful tools for controlling form behavior, but they operate at different levels.
UI Policies
UI Policies are client-side mechanisms that control form behavior in real-time as the user interacts with it. They can make fields mandatory, read-only, or visible, and show/hide related lists.
- Reverse if False: When checked, if the UI Policy condition is not met, the actions applied when the condition was met are reversed. For instance, if a field was made mandatory, it becomes optional again when the condition is false.
- On Load: If checked, the UI Policy is evaluated as soon as the form loads. If unchecked, it only triggers on user interaction or when specific fields change.
- Inherit: If checked, the UI Policy will apply to child tables that extend the table on which the UI Policy is defined.
- Run Scripts: Allows you to execute custom client-side JavaScript for more complex logic within UI Policies.
Can you write script in UI Policy? Yes, by enabling the “Run Scripts” checkbox and adding code to the “Client script” tab (for OnLoad, OnChange) or within the UI Policy Action’s “Script” field.
Data Policies
Data Policies enforce data integrity at both the client and server levels. They ensure that specific fields are mandatory, read-only, or hidden regardless of how the record is being accessed (form, API, import, etc.).
Key Differences:
- Scope: UI Policies are client-side; Data Policies are client and server-side.
- Enforcement: Data Policies enforce data policies universally, making them ideal for ensuring data consistency across all entry points.
Can you convert UI Policy as Data Policy? Yes, there’s a convenient “Convert to Data Policy” button on the UI Policy form, which helps in migrating UI Policies to Data Policies for broader enforcement.
Conclusion
Mastering Assignment Groups in ServiceNow is not just about understanding a single feature; it’s about grasping the interconnectedness of users, groups, roles, and the core ITSM processes. By leveraging the power of scripting, understanding fundamental table relationships, and utilizing tools like Business Rules, UI Policies, and Data Policies, you can build robust, efficient, and automated workflows. As you continue your journey with ServiceNow, remember that best practices, particularly around group-based role assignments and clear process definitions, are your strongest allies in delivering exceptional service. The Washington DC release and its predecessors offer a rich toolkit for achieving these goals, and a solid understanding of these concepts will undoubtedly make you a valuable asset to any ServiceNow team.