6/28/25, 9:45 PM Server-Side and Client-Side Scripting
Server-Side Scripting
1. What is the difference between GlideRecord and GlideAggregate? When would you
use each?
GlideRecord is used to perform database queries in ServiceNow. It is most commonly
used when you need to retrieve records and perform operations like insert, update, or
delete records.
Example:
javascript Copy Edit
var gr = new GlideRecord('incident'); gr.addQuery('active', true);
gr.query(); while (gr.next()) { gs.info(gr.number); }
Use Case: When you need to work with individual records.
GlideAggregate is used when you want to perform aggregation operations such as
count, sum, average, etc. It can be used to query and group records efficiently.
Example:
javascript Copy Edit
var ga = new GlideAggregate('incident'); ga.addAggregate('COUNT');
ga.addQuery('active', true); ga.query(); if (ga.next()) {
gs.info('Open incidents count: ' + ga.getAggregate('COUNT')); }
Use Case: When you need aggregate data, such as the count of records matching
a condition.
https://chatgpt.com/c/68601348-b92c-800e-be81-a31f4709d9b9 1/14
6/28/25, 9:45 PM Server-Side and Client-Side Scripting
2. How do you prevent a Business Rule from running recursively?
To prevent recursion in a Business Rule, you can use a flag stored in
the gs.getSession().put() method, or use a custom field to track whether the Business
Rule has already run.
javascript Copy Edit
if (!gs.getSession().get('business_rule_run')) {
gs.getSession().put('business_rule_run', true); // Your business rule logic
here } else { return; }
3. Write a script to get the number of open incidents assigned to the current user.
javascript Copy Edit
var gr = new GlideRecord('incident'); gr.addQuery('assigned_to',
gs.getUserID()); gr.addQuery('state', '!=', 6); // Open state gr.query(); var
count = gr.getRowCount(); gs.info('Open incidents: ' + count);
4. What is a Script Include? How do you make it accessible from the client side?
A Script Include is a reusable server-side script. To make it accessible from the client side,
you can use GlideAjax.
Example of Script Include:
javascript Copy Edit
var UserUtil = Class.create(); UserUtil.prototype = { initialize:
function() {}, getUserDetails: function(email) { var gr = new
GlideRecord('sys_user'); gr.addQuery('email', email); gr.query(); if
(gr.next()) { return gr.name; } return 'User not found'; } };
https://chatgpt.com/c/68601348-b92c-800e-be81-a31f4709d9b9 2/14
6/28/25, 9:45 PM Server-Side and Client-Side Scripting
To call it from a Client Script:
javascript Copy Edit
var ga = new GlideAjax('UserUtil'); ga.addParam('sys_id',
'getUserDetails'); ga.addParam('email', '
[email protected]');
ga.getXMLAnswer(function(response) { var userName =
response.responseXML.documentElement.getAttribute('answer');
gs.info(userName); });
5. Explain the execution order of Business Rules (Before, After, Async).
Before: Runs before the record is saved. This is useful for validating or modifying
record data before it is committed to the database.
After: Runs after the record is saved. This is useful for performing additional actions,
such as notifications or related record updates.
Async: Runs asynchronously after the record is saved, often used for non-blocking
tasks such as calling an external API or updating other systems.
6. What’s the use of current and previous objects in Business Rules?
current: Refers to the current state of the record being processed by the Business
Rule.
previous: Refers to the state of the record before the update was made. It is useful for
comparing changes (e.g., current.priority != previous.priority ).
7. How would you find the first 5 users who logged in today using GlideRecord?
javascript Copy Edit
https://chatgpt.com/c/68601348-b92c-800e-be81-a31f4709d9b9 3/14
6/28/25, 9:45 PM Server-Side and Client-Side Scripting
var gr = new GlideRecord('sys_user'); gr.addQuery('last_login_time', '>=',
gs.beginningOfToday()); gr.orderBy('last_login_time'); gr.setLimit(5);
gr.query(); while (gr.next()) { gs.info(gr.name); }
8. What’s the difference between gs.addInfoMessage() and gs.print()?
gs.addInfoMessage(): Displays a message to the user in the UI.
gs.print(): Outputs a message to the system log (useful for debugging).
9. Write a Script Include to return user details based on email.
javascript Copy Edit
var UserDetails = Class.create(); UserDetails.prototype = { initialize:
function() {}, getUserByEmail: function(email) { var user = new
GlideRecord('sys_user'); user.addQuery('email', email); user.query(); if
(user.next()) { return 'Name: ' + user.name + ', Department: ' +
user.department.name; } return 'User not found'; } };
10. How do you call one Script Include from another Script Include?
You can call a Script Include directly in another Script Include by creating an instance of
the class.
javascript Copy Edit
var UserDetails = new UserDetails(); var userInfo =
UserDetails.getUserByEmail('
[email protected]'); gs.info(userInfo);
https://chatgpt.com/c/68601348-b92c-800e-be81-a31f4709d9b9 4/14
6/28/25, 9:45 PM Server-Side and Client-Side Scripting
Client-Side Scripting
1. What are the types of Client Scripts in ServiceNow? Explain with use cases.
onLoad: Executes when a record is loaded. Useful for setting default values or UI logic.
onChange: Executes when a field’s value changes. Useful for dynamic form updates
based on user input.
onSubmit: Executes when the form is submitted. Useful for validation before saving a
record.
onCellEdit: Executes when a cell in a list is edited.
2. How do you call a Script Include from a Client Script?
Use GlideAjax to call a Script Include from the client side.
javascript Copy Edit
var ga = new GlideAjax('UserDetails'); ga.addParam('sys_id',
'getUserByEmail'); ga.addParam('email', '
[email protected]');
ga.getXMLAnswer(function(response) { var userInfo =
response.responseXML.documentElement.getAttribute('answer');
gs.info(userInfo); });
3. Explain the GlideAjax lifecycle with an example.
Client Script: Sends a request via GlideAjax to call the Script Include.
Script Include: Receives the request, processes it, and returns the result.
Client Script: Receives the response and updates the UI.
4. How do you hide a field based on the value of another field using a Client Script?
https://chatgpt.com/c/68601348-b92c-800e-be81-a31f4709d9b9 5/14
6/28/25, 9:45 PM Server-Side and Client-Side Scripting
javascript Copy Edit
function onChange(control, oldValue, newValue) { if (newValue ==
'specific_value') { g_form.setDisplay('field_name', false); } else {
g_form.setDisplay('field_name', true); } }
I’ll continue the rest of the questions in the next response! Would you like me to continue,
or would you prefer a break before the next section?
yes proceed and generate a pdf format
Updated saved memory
Great! Let me continue with the remaining answers and then generate the PDF for you.
5. Write a Client Script to validate if the caller is from the same department as the
logged-in user.
javascript Copy Edit
https://chatgpt.com/c/68601348-b92c-800e-be81-a31f4709d9b9 6/14
6/28/25, 9:45 PM Server-Side and Client-Side Scripting
function onSubmit() { var callerDepartment =
g_form.getReference('caller_id').department; var currentUserDepartment =
gs.getUser().getDepartment(); if (callerDepartment != currentUserDepartment) {
g_form.addErrorMessage('Caller must be from your department'); return false; }
return true; }
6. Difference between g_form.getReference() and GlideRecord?
g_form.getReference(): Fetches a reference field’s record. It returns
a GlideRecord object, allowing you to access fields from the referenced table.
Example:
javascript Copy Edit
var user = g_form.getReference('caller_id'); gs.info(user.name);
GlideRecord: Used to query any table in ServiceNow. It's a powerful object used for
CRUD operations.
Example:
javascript Copy Edit
var gr = new GlideRecord('incident'); gr.query();
7. What’s the purpose of g_scratchpad and where would you use it?
g_scratchpad is used to pass data between the server and client script. It's commonly used
in UI Scripts and Business Rules to temporarily hold and share data between server-side
and client-side code.
Example (Server-side):
https://chatgpt.com/c/68601348-b92c-800e-be81-a31f4709d9b9 7/14
6/28/25, 9:45 PM Server-Side and Client-Side Scripting
javascript Copy Edit
g_scratchpad.user_name = gs.getUser().name;
Example (Client-side):
javascript Copy Edit
alert(g_scratchpad.user_name);
8. How can you make a reference field mandatory only when another field is
selected?
javascript Copy Edit
function onChange(control, oldValue, newValue) { if (newValue ==
'specific_value') { g_form.setMandatory('reference_field', true); } else {
g_form.setMandatory('reference_field', false); } }
9. What’s the difference between onLoad and onChange Client Scripts?
onLoad: Executes when the form is loaded. Use it to set default field values, UI
changes, or logic when the form is first presented.
onChange: Executes when a field’s value changes. Use it to dynamically respond to
user input and modify form behavior.
10. Explain how to use g_form.clearOptions() and g_form.addOption() with an
example.
g_form.clearOptions(): Clears all options from a choice field.
g_form.addOption(): Adds an option to a choice field.
https://chatgpt.com/c/68601348-b92c-800e-be81-a31f4709d9b9 8/14
6/28/25, 9:45 PM Server-Side and Client-Side Scripting
Example:
javascript Copy Edit
function onLoad() { g_form.clearOptions('choice_field');
g_form.addOption('choice_field', 'option1', 'Option 1');
g_form.addOption('choice_field', 'option2', 'Option 2'); }
Advanced / Scenario-Based Questions
1. You need to prevent non-admin users from seeing VIP caller records. How would
you approach this?
You can create an Access Control Rule (ACL) for the VIP field on the Incident table. For
non-admin users, you can restrict access to that field by checking if the user has admin
privileges.
javascript Copy Edit
var user = gs.getUser(); if (!user.hasRole('admin')) { gs.addErrorMessage('You
do not have permission to view VIP records.'); return false; }
2. An approval workflow is not triggering. How would you debug this?
Check if the Workflow is correctly associated with the record.
Check Approval Rules to ensure conditions are being met.
Use System Logs to check for errors.
https://chatgpt.com/c/68601348-b92c-800e-be81-a31f4709d9b9 9/14
6/28/25, 9:45 PM Server-Side and Client-Side Scripting
Verify the State of the record (it may not trigger if the record is in a state that doesn’t
require approval).
3. How do you ensure that only one open incident exists per user at a time?
You can use a Before Business Rule to check if the user already has an open incident.
javascript Copy Edit
var gr = new GlideRecord('incident'); gr.addQuery('assigned_to',
current.assigned_to); gr.addQuery('state', '!=', 6); // Open state gr.query();
if (gr.next()) { gs.addErrorMessage('You already have an open incident.');
current.setAbortAction(true); }
4. You’ve written a Business Rule to update a field, but it’s not working. What steps
would you take to debug it?
Check the Business Rule logs for errors.
Verify conditions and ensure that they are correct.
Check if the field is set to Read-Only.
Test in different stages: Before, After, Async.
Use gs.info() or gs.error() to log specific values and flow.
5. Explain how you would calculate average resolution time for incidents and display
it on a dashboard.
Create a Scheduled Script that calculates the average resolution time and stores it in a
custom table or a report.
Example:
javascript
https://chatgpt.com/c/68601348-b92c-800e-be81-a31f4709d9b9 10/14
6/28/25, 9:45 PM Server-Side and Client-Side Scripting
Copy Edit
var gr = new GlideRecord('incident'); gr.addQuery('state', 'Closed');
gr.query(); var totalResolutionTime = 0; var count = 0; while (gr.next()) {
totalResolutionTime += gr.resolution_time; // Assuming it's stored in seconds
count++; } var avgResolutionTime = totalResolutionTime / count;
gs.info('Average Resolution Time: ' + avgResolutionTime);
6. A user says their catalog item isn't visible to them. How would you troubleshoot
this?
Check the Catalog Item’s visibility (conditions, roles).
Check the User’s Roles to ensure they have access to that catalog.
Review the Workflow and Approval Rules.
Check the Service Portal settings if applicable.
7. How would you schedule a script to run every Sunday at 2 AM?
You can create a Scheduled Job and set the schedule to run weekly on Sunday at 2 AM.
javascript Copy Edit
var job = new GlideRecord('sys_trigger'); job.initialize(); job.name = 'Weekly
Task'; job.script = 'Your Script Here'; job.next_action =
gs.dateGenerate(gs.nowDate(), '02:00:00'); job.repeat = 'Weekly';
job.day_of_week = 7; // Sunday job.insert();
8. What’s the use of the Display Business Rule, and when would you use it?
The Display Business Rule runs when a record is loaded and is used to set values on the
client-side form before rendering it in the UI. It’s helpful for scenarios where you need to
manipulate fields or data for display but not save it to the database.
https://chatgpt.com/c/68601348-b92c-800e-be81-a31f4709d9b9 11/14
6/28/25, 9:45 PM Server-Side and Client-Side Scripting
9. How do you migrate data or configuration between environments in ServiceNow?
Use Update Sets to capture configuration changes (e.g., Business Rules, Tables, ACLs).
Use ServiceNow’s Migration Tool for data migration.
Ensure proper testing in the Dev/QA environments before moving to Production.
10. Explain how ACLs work and how to troubleshoot access issues.
Access Control Rules (ACLs) define who can access a resource (like records or fields). You
can troubleshoot access issues by:
Reviewing the ACLs associated with the resource.
Checking if the user has the necessary roles.
Using System Logs to identify permission errors.
Bonus: Small Code Snippets
1. Write a script to list all active users in the IT department.
javascript Copy Edit
var gr = new GlideRecord('sys_user'); gr.addQuery('department', 'IT');
gr.addQuery('active', true); gr.query(); while (gr.next()) { gs.info(gr.name);
}
2. GlideAjax script pair to get the logged-in user's manager name.
Script Include:
https://chatgpt.com/c/68601348-b92c-800e-be81-a31f4709d9b9 12/14
6/28/25, 9:45 PM Server-Side and Client-Side Scripting
javascript Copy Edit
var UserDetails = Class.create(); UserDetails.prototype = { initialize:
function() {}, getManagerName: function() { var user = gs.getUser(); var gr =
new GlideRecord('sys_user'); if (gr.get(user.getManager())) { return gr.name;
} return 'No manager assigned'; } };
Client Script:
javascript Copy Edit
var ga = new GlideAjax('UserDetails'); ga.addParam('sys_id',
'getManagerName'); ga.getXMLAnswer(function(response) { var managerName =
response.responseXML.documentElement.getAttribute('answer'); alert('Manager: '
+ managerName); });
3. Business Rule to update incident priority based on impact and urgency.
javascript Copy Edit
(function executeRule(current, previous /*null when async*/) { if
(current.impact == 1 && current.urgency == 1) { current.priority = 1; //
Critical } else if (current.impact == 2 || current.urgency == 2) {
current.priority = 2; // High } else { current.priority = 3; // Medium } })
(current, previous);
4. Client Script to restrict closing an incident unless resolution notes are filled.
javascript Copy Edit
function onSubmit() { if (g_form.getValue('state') == 6 &&
!g_form.getValue('resolution_notes')) { g_form.addErrorMessage('Resolution
notes must be filled before closing.'); return false; } return true; }
https://chatgpt.com/c/68601348-b92c-800e-be81-a31f4709d9b9 13/14
6/28/25, 9:45 PM Server-Side and Client-Side Scripting
5. Scheduled Job to deactivate users not logged in for 90 days.
javascript Copy Edit
var gr = new GlideRecord('sys_user'); gr.addQuery('last_login_time', '<',
gs.dateGenerate(gs.nowDate(), '00:00:00')); gr.addQuery('active', true);
gr.query(); while (gr.next()) { gr.active = false; gr.update(); }
https://chatgpt.com/c/68601348-b92c-800e-be81-a31f4709d9b9 14/14