ScriptingwithGK
Master the Art of ServiceNow Scripting
Prepared By:
Gopi Krishna
ServiceNow Developer | Trainer | Content Creator
About this Guide:
ScriptingwithGK is a dedicated collection of real-time scripting scenarios, best practices, and
interview questions designed to help learners and professionals master server-side and client-
side scripting in the ServiceNow platform. This guide is ideal for ServiceNow Developers
preparing for interviews, upskilling in scripting, or teaching concepts to others.
Covered Topics Include:
• Business Rules
• Client Scripts
• Script Includes
• Background Scripts
• GlideForm, GlideRecord, Glide DateTime, Glide Aggregate, Glide Session
• Scripting Use Cases from ITSM Projects
Note:
All examples in this document are structured for easy understanding and direct application in
real-world ServiceNow environments. Script blocks are kept clean, modular, and interview
ready.
Contents
Background Scripts.................................................................................................................................. 3
Client Scripts ......................................................................................................................................... 13
Script Include or Scheduled Job ............................................................................................................ 19
Business Rules ....................................................................................................................................... 21
Background Scripts
1. Scenario: Get Roles of Current Logged-in User
Code:
var userId = gs.getUserID();
var userRoles = [];
var grRole = new GlideRecord('sys_user_has_role');
grRole.addQuery('user', userId);
grRole.query();
while (grRole.next()) {
var roleName = grRole.role.name.toString();
userRoles.push(roleName);
}
gs.info("Roles of current user: " + userRoles.join(', '));
2. Scenario: Get Users for a Particular Role (example – 'admin')
Code:
var roleName = 'admin';
var usersWithRole = [];
var grRole = new GlideRecord('sys_user_role');
grRole.addQuery('name', roleName);
grRole.query();
if (grRole.next()) {
var roleSysId = grRole.getUniqueValue();
var grUserRole = new GlideRecord('sys_user_has_role');
grUserRole.addQuery('role', roleSysId);
grUserRole.query();
while (grUserRole.next()) {
var userName = grUserRole.user.name.toString();
usersWithRole.push(userName);
}
gs.info("Users with role '" + roleName + "': " + usersWithRole.join(',
'));
} else {
gs.info("Role '" + roleName + "' not found.");
}
3. Scenario: Get Groups of Current Logged-in User
Code:
var currentUserId = gs.getUserID();
var userGroups = [];
var grGroupMember = new GlideRecord('sys_user_grmember');
grGroupMember.addQuery('user', currentUserId);
grGroupMember.query();
while (grGroupMember.next()) {
var groupName = grGroupMember.group.name.toString();
userGroups.push(groupName);
}
gs.info("Groups for current user: " + userGroups.join(', '));
4. Scenario: Get Users for a Particular Group
Code:
var groupName = 'Application Development';
var userList = [];
// Step 1: Get the group sys_id based on name
var grGroup = new GlideRecord('sys_user_group');
grGroup.addQuery('name', groupName);
grGroup.query();
if (grGroup.next()) {
var groupSysId = grGroup.sys_id.toString();
// Step 2: Fetch all users from sys_user_grmember table
var grGroupMember = new GlideRecord('sys_user_grmember');
grGroupMember.addQuery('group', groupSysId);
grGroupMember.query();
while (grGroupMember.next()) {
var userName = grGroupMember.user.name.toString();
userList.push(userName);
}
gs.info("Users in '" + groupName + "': " + userList.join(', '));
} else {
gs.info("Group '" + groupName + "' not found.");
}
5. Scenario: Get Directly Assigned Roles of Current Logged-in User
Code:
gs.info(gs.getUser().getUserRoles());
6. Scenario: Get the Actual Name of the Current Logged-in User
Code:
gs.info(gs.getUser().getDisplayName());
7. Scenario: Get the Last 10 Closed Incidents
Code:
var inc = new GlideRecord('incident');
inc.addQuery('state', '7'); // State = Closed
inc.orderByDesc('sys_updated_on'); // Sort by last updated
inc.setLimit(10); // Only fetch 10 records
inc.query();
while (inc.next()) {
gs.info(inc.number + " → Caller: " + inc.caller_id.getDisplayValue());
}
8. Scenario: Get Active P1 and P2 Incidents with Category = 'inquiry'
Code:
var inc = new GlideRecord('incident');
inc.addQuery('priority', 'IN', '1,2'); // Priority P1 and P2
inc.addQuery('category', 'inquiry'); // Category = 'inquiry'
inc.addActiveQuery(); // Only active incidents
inc.query();
while (inc.next()) {
gs.info(inc.number + " → Priority: " + inc.priority.getDisplayValue() +
" → Category: " + inc.category);
}
gs.info("Total active P1/P2 incidents with category 'inquiry': " +
inc.getRowCount());
9. Scenario: Get Current Logged-in User's Incidents
Code:
var inc = new GlideRecord('incident');
inc.addQuery('caller_idDYNAMIC90d1921e5f510100a9ad2572f2b477fe');
inc.addActiveQuery();
inc.query();
while (inc.next()) {
gs.info(inc.number + ":-" + inc.short_description);
}
gs.info(inc.getRowCount());
10. Scenario: Get All Active Incidents Excluding Closed & Cancelled
Code:
var inc = new GlideRecord('incident');
inc.addQuery('state', 'NOT IN', '7,8'); // Exclude Closed (7) and Cancelled
(8)
inc.addActiveQuery(); // Only active incidents
inc.query();
while (inc.next()) {
gs.info(inc.number + " → State: " + inc.state.getDisplayValue());
}
gs.info("Total active incidents excluding Closed & Cancelled: " +
inc.getRowCount());
11. Scenario: Update all incidents in the "On Hold" state that haven’t
been updated in 3 days
Code:
var gr = new GlideRecord('incident');
gr.addQuery('state', 3); // On Hold
gr.addQuery('sys_updated_on', '<=', gs.daysAgo(3)); // Not updated in 3
days
gr.query();
while (gr.next()) {
gr.state = 1; // Set to New
gr.update();
}
12. Scenario: Retrieve all open incidents assigned to the logged-in
user
Code:
var gr = new GlideRecord('incident');
gr.addQuery('assigned_to', gs.getUserID());
gr.addQuery('state', '!=', 7); // Not Closed
gr.query();
while (gr.next()) {
gs.info("My Incident: " + gr.number);
}
13. Scenario: Get the count of incidents grouped by priority.
Code:
var ga = new GlideAggregate('incident'); ga.addAggregate('COUNT');
ga.groupBy('priority');
ga.query();
while (ga.next()) {
gs.info("Priority " + ga.priority + ": " + ga.getAggregate('COUNT'));
}
14. Scenario: Top 3 Categories of Incidents Logged
Code:
var ga = new GlideAggregate('incident'); ga.addAggregate('COUNT');
ga.groupBy('category');
ga.orderByAggregate('COUNT'); ga.setLimit(2);
ga.query();
while (ga.next()) {
gs.info(ga.category + ": " + ga.getAggregate('COUNT'));
}
15. Scenario: Set the due date as 24 business hours from creation.
(Business Rule)
Code:
var gdt = new GlideDateTime();
gdt.addDays(1); // Add 1 day current.due_date = gdt;
16. Scenario: Get duration between opened_at and resolved_at on
an incident
Code:
var start = new GlideDateTime(current.opened_at);
var end = new GlideDateTime(current.resolved_at);
var diff = GlideDateTime.subtract(end, start);
gs.info("Time to resolve: " + diff.getDisplayValue());
17. Scenario: Close incidents that were resolved over a week ago.
Code:
var gr = new GlideRecord('incident');
var gdt = new GlideDateTime();
gdt.addDaysUTC(-7);
gr.addQuery('resolved_at', '<=', gdt);
gr.addQuery('state', 6); // Resolved
gr.query();
while (gr.next()) {
gr.state = 7; // Closed gr.update();
}
18. Scenario: Add a manager to the watch list for all P1 incidents.
Code:
var gr = new GlideRecord('incident');
gr.addQuery('priority', 1); // High gr.query();
while (gr.next()) {
gr.watch_list += ',manager_user_id'; // Replace with actual sys_id or user
ID gr.update();
}
19. Scenario: Get a report of how many incidents each user has
raised
Code:
var ga = new GlideAggregate('incident');
ga.addAggregate('COUNT');
ga.groupBy('caller_id');
ga.query();
while (ga.next()) {
gs.print(ga.caller_id.getDisplayValue() + ": " + ga.getAggregate('COUNT'));
}
20. Scenario: List top 5 users with the most open incidents
Code:
var ga = new GlideAggregate('incident');
ga.addQuery('state', '!=', 7); // Not Closed ga.addAggregate('COUNT');
ga.groupBy('caller_id');
ga.orderByAggregate('COUNT');
ga.setLimit(5);
ga.query();
while (ga.next()) {
gs.print(ga.caller_id.getDisplayValue() + ": " + ga.getAggregate('COUNT'));
}
21. Scenario: Log details about the current session for
troubleshooting
Code:
gs.print("User ID: " + gs.getUserID());
gs.print("User Name: " + gs.getUserName());
gs.print("User Display Name: " + gs.getUserDisplayName());
gs.print("Has Admin Role: " + gs.hasRole('admin'));
22. Scenario: List all open incidents older than 30 days
Code:
var gdt = new GlideDateTime();
gdt.addDaysUTC(-30);
var gr = new GlideRecord('incident');
gr.addQuery('opened_at', '<=', gdt);
gr.addQuery('state', '!=', 7); // Not Closed gr.query();
while (gr.next()) {
gs.print(gr.number + " opened on " + gr.opened_at)
};
23. Scenario: Calculate how many days an incident has been open.
Code:
var gr = new GlideRecord('incident');
gr.addQuery('state', '!=', 7); // Not Closed gr.query();
while (gr.next()) {
var opened = new GlideDateTime(gr.opened_at);
var now = new GlideDateTime();
var diff = GlideDateTime.subtract(now, opened);
gs.print(gr.number + " | Days Open: " + diff.getRoundedDayPart());
}
}
24. Scenario: Deactivate All Users Who Have Not Logged In for 90
Days
Code:
var cutoffDate = new GlideDateTime(); cutoffDate.addDaysUTC(-90);
var gr = new GlideRecord('sys_user');
gr.addQuery('last_login_time', '<=', cutoffDate);
gr.addQuery('active', true);
gr.query();
while (gr.next()) {
gr.active = false;
gr.update();
}
25. Scenario: Find All Incidents Assigned to a Group but Without an
Assignee
Code:
var gr = new GlideRecord('incident');
gr.addNotNullQuery('assignment_group');
gr.addNullQuery('assigned_to');
gr.query();
while (gr.next()) {
gs.print(gr.number + " has a group but no assignee.");
}
26. Scenario: Update All Catalog Tasks Related to a Request Item
Code:
var gr = new GlideRecord('sc_task');
gr.addQuery('request_item', 'aeed229047801200e0ef563dbb9a71c2'); // Replace
with actual RITM sys_id or number
gr.query();
while (gr.next()) {
gr.state = 3; // Closed Complete gr.update();
}
27. Scenario: Find Users Belonging to Multiple Groups
Code:
var users = {};
var gr = new GlideRecord('sys_user_grmember');
gr.query();
while (gr.next()) {
var userId = gr.user.name.toString();
users[userId] = (users[userId] || 0) + 1;
}
for (var u in users) {
if (users[u] > 1) gs.print("User: " + u + " is in " + users[u] + "
groups.");
}
28. Scenario: Find Incidents Without a Category Set
Code:
var gr = new GlideRecord('incident');
gr.addNullQuery('category');
gr.query();
while (gr.next()) {
gs.print("Incident " + gr.number + " has no category.");
}
29. Scenario: List Incidents Opened During Business Hours Only
Code:
var gr = new GlideRecord('incident');
gr.query();
while (gr.next()) {
var openedHour = new GlideDateTime(gr.opened_at).getHourOfDayUTC();
if (openedHour >= 9 && openedHour <= 17) {
gs.print("Business Hour Incident: " + gr.number);
}
}
30. Scenario: Add Custom Hours and Minutes to a Date
Code:
var gdt = new GlideDateTime();
gdt.addHours(3);
gdt.addMinutes(30);
gs.print("Time after 3h 30m: " + gdt.getDisplayValue());
31. Scenario: Update All Incidents With a Specific Caller to a New
Assignment Group
Code:
var gr = new GlideRecord('incident');
gr.addQuery('caller_id.name', 'John Doe'); // Replace with actual caller
name gr.query();
while (gr.next()) {
gr.assignment_group.setDisplayValue('IT Support'); // Use group name
gr.update();
}
32. Scenario: Delete All Test Change Requests With a Speciflc
Keyword
Code:
var gr = new GlideRecord('change_request');
gr.addQuery('short_description', 'CONTAINS', 'Test Change');
gr.query();
while (gr.next()) {
gr.deleteRecord();
}
33. Scenario: Set ‘Watch List’ on All Critical Incidents Opened This
Month
Code:
var start = new GlideDateTime();
start.setDisplayValue('2025-04-01 00:00:00'); // Update to this month's
start
var gr = new GlideRecord('incident');
gr.addQuery('opened_at', '>=', start);
gr.addQuery('priority', 1);
gr.query();
while (gr.next()) {
gr.watch_list = '
[email protected],
[email protected]';
gr.update();
}
34. Scenario: List All Users Without Email Address
Code:
var gr = new GlideRecord('sys_user');
gr.addNullQuery('email');
gr.query();
while (gr.next()) {
gs.print("User without email: " + gr.name);
}
35. Scenario: Update Impact of All Incidents with a Specific
Configuration Item
Code:
var gr = new GlideRecord('incident');
gr.addQuery('cmdb_ci.name', 'Email Server');
gr.query();
while (gr.next()) {
gr.impact = 1; // High Impact gr.update();
}
36. Scenario: Find Active Tasks Not Updated in the Last 5 Days
Code:
var date = new GlideDateTime();
date.addDaysUTC(-5);
var gr = new GlideRecord('task');
gr.addQuery('active', true);
gr.addQuery('sys_updated_on', '<=', date);
gr.query();
while (gr.next()) {
gs.print(gr.number + " is stale since " +
gr.sys_updated_on.getDisplayValue());
}
Client Scripts
37. Scenario: Make a field read-only when the form loads
Application: Client Script
Type: onLoad
Code:
function onLoad() {
// Make the 'short_description' field read-only
g_form.setReadOnly('short_description', true);
}
38. Scenario: Set a default value for a field when the form loads
Application: Client Script
Type: onLoad
Code:
function onLoad() {
// Set the default value of the 'priority' field to '3' (Low)
g_form.setValue('priority', '3');
}
39. Scenario: Dynamically make a field mandatory based on another
field's value
Application: Client Script
Type: onChange
Code:
function onChange(control, oldValue, newValue, isLoading) {
// Check if the new value is '1' (example: Priority = 1)
if (newValue === '1') {
// Make the 'impact' field mandatory
g_form.setMandatory('impact', true);
} else {
// Remove the mandatory condition for 'impact' field
g_form.setMandatory('impact', false);
}
}
40. Scenario: Hide a field using Client Script
Application: Client Script
Type: onLoad
Code:
function onLoad() {
// Hide the 'description' field
g_form.setDisplay('description', false);
}
41. Scenario: Prevent form submission based on a condition
Application: Client Script
Type: onSubmit
Code:
function onSubmit() {
// Check if 'priority' is 1 (high priority) and 'description' is empty
if (g_form.getValue('priority') == '1' &&
!g_form.getValue('description')) {
// Display an alert if the condition is met
alert('Description is required for high priority incidents.');
// Prevent form submission
return false;
}
// Allow form submission if condition is not met
return true;
}
42. Scenario: Disable a field only when a certain condition is met
Application: Client Script
Type: onLoad
Code:
function onLoad() {
// Check if 'priority' is '1' (high priority)
if (g_form.getValue('priority') == '1') {
// Disable the 'description' field (make it read-only)
g_form.setReadOnly('description', true);
}
}
43. Scenario: Prevent a field from being edited once set
Application: Client Script
Type: onChange
Code:
function onChange(control, oldValue, newValue, isLoading) {
// Check if the form is not loading and there is an actual change in
the field value
if (!isLoading && oldValue && oldValue !== newValue) {
// Revert the 'category' field to its previous value (oldValue)
g_form.setValue('category', oldValue);
// Display an information message informing the user that the
'category' field cannot be changed
g_form.addInfoMessage('Category cannot be changed once set.');
}
}
44. Scenario: Auto-populate a reference field based on conditions
Application: Client Script
Type: onChange
Code
function onChange(control, oldValue, newValue, isLoading) {
// Check if the new value is 'hardware'
if (newValue == 'hardware') {
// Set the 'assignment_group' field to a specific sys_id when
'hardware' is selected
g_form.setValue('assignment_group',
'287ebd7da9fe198100f92cc8d1d2154e'); // Replace with actual sys_id
}
}
45. Scenario: Prevent form submission with custom validation
Application: Client Script
Type: onSubmit
Code:
function onSubmit() {
// Get the value of the 'short_description' field
var shortDesc = g_form.getValue('short_description');
// Check if the 'short_description' contains the word 'test' (case-
insensitive)
if (shortDesc.toLowerCase().includes('test')) {
// Add an error message if 'test' is found
g_form.addErrorMessage('Short Description cannot contain "test".');
// Prevent form submission by returning false
return false;
}
// Allow form submission if the condition is not met
return true;
}
46. Scenario: Based on current date, add 5 days to current date and
due date should return based on start date
Application: Client Script
Type: onChange
Code:
function onChange(control, oldValue, newValue, isLoading, isTemplate) {
// Exit if the form is still loading or if the new value is empty
if (isLoading || newValue === '') {
return;
}
// Set the number of days to add to the current date (5 days)
var daysadded = "5";
// Get the value of the 'opened_at' field and convert it to a Date
object
var opened = new Date(g_form.getValue('opened_at'));
// Initialize an empty variable to hold the calculated due date
var duedate = "";
// Get the day of the month from the 'opened_at' date
var openedate = opened.getDate();
// Add the specified number of days (5) to the current day of the
'opened_at' date
var totaldays = parseInt(openedate) + parseInt(daysadded);
// Set the new due date by updating the day of the month
opened.setDate(totaldays);
// Format the new due date based on the user's date and time format
settings
duedate = formatDate(opened, g_user_date_time_format);
// Set the 'due_date' field value to the newly calculated due date
g_form.setValue('due_date', duedate);
}
47. Scenario: Date field should not allow past dates
Application: Client Script
Type: onSubmit
Code:
function onSubmit() {
// Get the current date and time
var presentdate = new Date();
// Get the 'opened_at' date field value and convert it to a Date object
var startdate = new Date(g_form.getValue('opened_at'));
// Compare if the 'opened_at' date is in the past compared to the
current date
if (presentdate.valueOf() > startdate.valueOf()) {
// If the selected date is in the past, clear the 'opened_at' field
g_form.clearValue('opened_at');
// Show an alert to the user indicating that past dates are not
allowed
alert('You cannot choose a past date');
// Prevent the form from being submitted by returning false
return false;
}
// Allow the form submission if the date is valid (not in the past)
return true;
}
48. Scenario: End Date should be after Start Date
Application: Client Script
Type: onSubmit
Code:
function onSubmit() {
// Get the 'due_date' field value and convert it to a Date object
var duedate = new Date(g_form.getValue('due_date'));
// Get the 'opened_at' (Start Date) field value and convert it to a
Date object
var startdate = new Date(g_form.getValue('opened_at'));
// Compare if the 'due_date' is after the 'opened_at' (Start Date)
if (duedate.valueOf() > startdate.valueOf()) {
// If the 'due_date' is valid (after the Start Date), display an
info message
g_form.addInfoMessage("true");
} else {
// If the 'due_date' is before or the same as the Start Date, show
an alert
alert("End Date should be after Start Date.");
// Clear the 'due_date' field as it doesn't meet the condition
g_form.clearValue('due_date');
// Prevent the form submission by returning false
return false;
}
// Allow the form submission if the dates are valid
return true;
}
49. Scenario: Users should only be able to enter End date between
today and the coming 10 days
Application: Client Script
Type: onSubmit
Code:
function onSubmit() {
// Get the 'due_date' field value and convert it to a Date object
var enddate = new Date(g_form.getValue('due_date'));
// Get today's date
var todayJSdate = new Date();
// Calculate the time difference between the 'due_date' and today's
date in milliseconds
var timediff = enddate.getTime() - todayJSdate.getTime();
// Convert the time difference from milliseconds to days
var datediff = timediff / (24 * 60 * 60 * 1000);
// Check if the 'due_date' is more than 10 days in the future
if (datediff > 10) {
// If the due date is beyond 10 days, show an alert
alert("Please select a due date within 10 days from today");
// Clear the 'due_date' field as it doesn't meet the condition
g_form.setValue('due_date', '');
// Prevent the form submission by returning false
return false;
}
// Allow the form submission if the due date is within the 10-day range
return true;
}
50. Scenario: How to restrict past/future date selection
Application: Client Script
Type: onSubmit
Code:
function onSubmit() {
// Get the 'opened_at' field value and convert it to a Date object
var sdate = new Date(g_form.getValue('opened_at'));
// Get today's date
var odate = new Date();
// Compare only the date (without time) of 'opened_at' and today's date
if (odate.toDateString() !== sdate.toDateString()) {
// If the selected date is not today's date, show an error message
g_form.addErrorMessage('Please select current date');
// Clear the 'opened_at' field as it doesn't meet the condition
g_form.clearValue('opened_at');
// Prevent the form submission by returning false
return false;
}
// Allow the form submission if the date is today's date
return true;
}
Script Include or Scheduled Job
51. Scenario: Automatically Close Incidents After 7 Days
Application: Server-side Script
Type: Scheduled Job or Script Include
Code:
var gr = new GlideRecord('incident');
// Add a query to find incidents where the state is 'Resolved' (state = 6)
gr.addQuery('state', 6);
// Add another condition to find incidents that were resolved at least 7
days ago
gr.addQuery('resolved_at', '<=', gs.daysAgo(7));
// Execute the query
gr.query();
// Loop through each matching incident
while (gr.next()) {
// Change the state to 'Closed' (state = 7)
gr.state = 7;
// Add a work note indicating the automatic closure
gr.work_notes = "Incident automatically closed after 7 days in resolved
state.";
// Save the changes
gr.update();
}
52. Scenario: Auto-Close Incidents with No Updates for 14 Days
Application: Server-side Script
Type: Scheduled Job or Script Include
Code:
// Create a GlideRecord object for the 'incident' table
var gr = new GlideRecord('incident');
// Query for incidents that are NOT already Closed (state != 7)
gr.addQuery('state', '!=', 7);
// Add another condition to get incidents not updated in the last 14 days
gr.addQuery('sys_updated_on', '<=', gs.daysAgo(14));
// Execute the query
gr.query();
// Loop through all matching incident records
while (gr.next()) {
// Set the state to 'Closed' (state = 7)
gr.state = 7;
// Add a work note mentioning why the incident was closed
gr.work_notes = "Incident auto-closed due to inactivity.";
// Update the incident record in the database
gr.update();
}
53. Scenario: Escalate Incidents That Haven’t Been Assigned in 4
Hours
Application: Server-side Script
Type: Scheduled Job or Script Include
Code:
// Create a GlideRecord object for the 'incident' table
var gr = new GlideRecord('incident');
// Fetch incidents that are NOT in the 'Closed' state
gr.addQuery('state', '!=', 7);
// Only select incidents that have NOT been assigned to anyone
gr.addQuery('assigned_to', 'NULL');
// Find incidents created more than 4 hours ago
gr.addQuery('sys_created_on', '<=', gs.hoursAgo(4));
// Execute the query
gr.query();
// Loop through each matching record
while (gr.next()) {
// Set a custom field (e.g., u_escalated) to true to flag it as
escalated
gr.u_escalated = true;
// Add a work note explaining the reason for escalation
gr.work_notes = "Incident escalated due to lack of assignment.";
// Save the updated record
gr.update();
}
Business Rules
54. Scenario: Send an Email Notification When a High-Priority
Incident is Created
Application: Server-side Script
Type: Business Rule: After Insert
Code:
if (current.priority == 1 || current.priority == 2) {
var emailBody = "A high-priority incident (" + current.number + ") has
been created. \n\n" + "Short Description: " + current.short_description;
// Trigger the custom event with recipient email and message
gs.eventQueue("incident.high_priority", current,
"
[email protected]", emailBody);
}
55. Scenario: Notify Manager When Priority 1 Incident is Assigned
Application: Server-side Script
Type: Business Rule: after Update
Code:
if (current.priority == 1 && current.assigned_to && previous.assigned_to !=
current.assigned_to) {
var userGR = new GlideRecord('sys_user');
userGR.get(current.assigned_to);
if (userGR.manager) {
// Trigger custom event to notify manager
gs.eventQueue("incident.p1_assignment", current, userGR.manager,
current.assigned_to);
}
}
56. Scenario: Prevent Self-Approval of Change Requests
Application: Business Rule: Before
When to Run: Update
Table: change_request
Code:
if (current.approver == gs.getUserID()) {
gs.addErrorMessage("You cannot approve your own change request.");
current.setAbortAction(true); // Stop the record update
}
57. Scenario: Restrict Attachment Types in Service Catalog Requests
Application: Server-side Script
Type: Business Rule: Before
When to Run: Insert
Table: sc_request
Code:
var sa = new GlideSysAttachment();
var attachments = sa.getAttachments(current);
while (attachments.next()) {
var fileName = attachments.file_name.toLowerCase();
if (fileName.endsWith('.exe') || fileName.endsWith('.bat') ||
fileName.endsWith('.cmd')) {
gs.addErrorMessage("Executable files are not allowed.");
current.setAbortAction(true); // Stop submission of the request
}
}
58. Scenario: Enforce Work Notes on High-Priority Incidents
Application: Server-side Script
Type: Business Rule: Before
When to Run: Update
Table: incident
Code:
if ((current.priority == 1 || current.priority == 2) &&
!current.work_notes) {
gs.addErrorMessage("You must provide work notes for high-priority
incidents.");
current.setAbortAction(true);
}
59. Scenario: Automatically Update Incident Priority Based on
Business Impact
Application: Server-side Script
Type: Business Rule: Before
When to Run: Insert
Table: incident
Code:
if (current.impact == 1 && current.urgency == 1) {
current.priority = 1; // Critical
} else if (current.impact <= 2 && current.urgency <= 2) {
current.priority = 2; // High
} else if (current.impact == 2 && current.urgency == 2) {
current.priority = 3; // Moderate
} else if (current.impact <= 3 && current.urgency == 3) {
current.priority = 4; // Low
} else {
current.priority = 5; // Planning
}
60. Scenario: Prevent Ticket Reassignment to the Same Agent
Application: Server-side Script
Type: Business Rule: Before
When to Run: Update
Table: incident
Code:
if (current.assigned_to == previous.assigned_to) {
gs.addErrorMessage("You cannot reassign the incident to the same
agent.");
current.setAbortAction(true);
}
61. Scenario: Copy Attachments from One Record to Another
Application: Server-side Script
Type: Business Rule: After
When to Run: Insert
Table: problem
Code:
var sa = new GlideSysAttachment();
sa.copy("incident", sourceIncidentSysId, "problem", current.sys_id);
62. Scenario: Validate Phone Number Format
Application: Server-side Script
Type: Business Rule: Before
When to Run: Insert
Table: incident
Code:
var phoneRegex = /^\+?\d{10,15}$/; // Matches +1234567890 format
if (!phoneRegex.test(current.u_phone_number)) {
gs.addErrorMessage("Invalid phone number format. Use +1234567890
format.");
current.setAbortAction(true);
}
63. Scenario: Prevent Users from Assigning Incidents to Themselves
Application: Server-side Script
Type: Business Rule: Before
When to Run: Update
Table: incident
Code:
if (current.assigned_to == gs.getUserID()) {
gs.addErrorMessage("You cannot assign incidents to yourself.");
current.setAbortAction(true);
}
64. Scenario: Prevent Users from Changing Their Own Details
Application: Server-side Script
Type: Business Rule: Before
When to Run: Update
Table: sys_user
Code:
if (current.sys_id == gs.getUserID()) {
gs.addErrorMessage("You cannot modify your own roles.");
current.setAbortAction(true);
}
65. Scenario: Automatically Populate Parent Incident Based on
Similar Open Incidents
Application: Server-side Script
Type: Business Rule: Before
When to Run: Insert
Table: incident
Code:
var parentGR = new GlideRecord('incident');
parentGR.addQuery('short_description', 'CONTAINS',
current.short_description);
parentGR.addQuery('state', '!=', 7); // 7 = Closed
parentGR.orderByDesc('sys_created_on');
parentGR.query();
if (parentGR.next()) {
current.parent = parentGR.sys_id;
}
66. Scenario: Prevent Deletion of Records
Application: Server-side Script
Type: Business Rule: Before
When to Run: Delete
Table: incident
Code:
if (current.priority == 1) {
gs.addErrorMessage("High-priority incidents cannot be deleted!");
current.setAbortAction(true);
}
67. Scenario: Create a GlideRecord in Business Rule
Application: Server-side Script
Type: Business Rule: After
When to Run: Update
Table: incident
Code
if (current.state == 6 && previous.state != 6) { // 6 = Resolved
var problemGR = new GlideRecord('problem');
problemGR.initialize();
problemGR.short_description = "Problem related to incident " +
current.number;
problemGR.correlation_id = current.sys_id;
problemGR.insert();
}
68. Scenario: Prevent Updating an Incident If Conditions Are Not Met
Application: Server-side Script
Type: Business Rule: Before
When to Run: Update
Table: incident
Code:
if (current.state == 6 && !current.close_code) { // 6 = Resolved
gs.addErrorMessage("You must provide a resolution code before closing
this incident.");
current.setAbortAction(true);
}
69. Scenario: Auto-Generate a Knowledge Article from a Resolved
Incident
Application: Server-side Script
Type: Business Rule: After
When to Run: Update
Table: incident
Code:
if (current.state == 6 && previous.state != 6) { // 6 = Resolved
var kbGR = new GlideRecord('kb_knowledge');
kbGR.initialize();
kbGR.short_description = "Solution for Incident " + current.number;
kbGR.text = current.close_notes;
kbGR.kb_category = "Incident Resolutions"; // Adjust as needed
kbGR.workflow_state = "draft"; // Set to draft for review
kbGR.insert();
}
70. Scenario: Automatically Add Users to a Group When They Are
Created
Application: Server-side Script
Type: Business Rule: After
When to Run: Insert
Table: sys_user
Code:
var groupGR = new GlideRecord('sys_user_group');
groupGR.addQuery('name', 'New Hires');
groupGR.query();
if (groupGR.next()) {
var groupMember = new GlideRecord('sys_user_grmember');
groupMember.initialize();
groupMember.user = current.sys_id;
groupMember.group = groupGR.sys_id;
groupMember.insert();
}
71. Scenario: Auto-Populate a Field on Insert
Application: Server-side Script
Type: Business Rule: Before
When to Run: Insert
Table: incident
Code:
(function executeRule(current, previous /*null when async*/) {
if (!current.description) {
current.description = "New Incident Reported";
}
})(current, previous);
72. Scenario: Restrict Updates Based on Field Change
Application: Server-side Script
Type: Business Rule: Before
When to Run: Update
Table: incident
Code:
if (current.priority != previous.priority) {
gs.addErrorMessage("Priority cannot be changed manually.");
current.priority = previous.priority; // Revert the priority back to
its previous value
}
73. Scenario: Auto-Assign Tasks to a Group
Application: Server-side Script
Type: Business Rule: Before
When to Run: Insert
Table: incident
Code:
if (!current.assignment_group) {
var grp = new GlideRecord('sys_user_group');
grp.addQuery('name', 'Application Development');
grp.query();
if (grp.next()) {
current.assignment_group = grp.sys_id;
}
}
75. Scenario: Query Another Table Before Assignment
Application: Server-side Script
Type: Business Rule: Before
When to Run: Update
Table: incident
Code:
var userGR = new GlideRecord('sys_user_grmember');
userGR.addQuery('user', current.assigned_to);
userGR.addQuery('group.name', 'Application Development');
userGR.query();
if (!userGR.next()) {
gs.addErrorMessage("User must be part of the Application Development
group!");
current.setAbortAction(true);
}