ServiceNow Scripting Scenarios Answers
Okay, here are solutions for each of the scripting scenarios, presented in Markdown format. I'll provide concise, functional scripts that you can adapt and expand upon. I'll use JavaScript, the primary scripting language within ServiceNow. I'll also include comments to explain key parts of the code.
Important Considerations:
- Error Handling: For brevity, I've omitted extensive error handling in most scripts. In a production environment, you must add robust error handling (try/catch blocks, logging, etc.).
- Best Practices: These scripts are examples. Always follow ServiceNow best practices, including using Script Includes for reusable code, avoiding global business rules where possible, and thoroughly testing your scripts.
-
Table and Field Names: I'll use common ServiceNow table and field names (e.g.,
incident
,sys_user
,short_description
). You may need to adjust these if your instance uses different names. - Context: Remember the context where these scripts would run (Client Script, Business Rule, Scheduled Job, etc.). I've indicated this in the comments.
- GlideRecord Secure: These scripts have been updated to use GlideRecordSecure wherever possible, which is a best practice for security.
Basics
1. Generate Unique Identifier:
// (Business Rule - Before Insert - On your custom table)
(function executeRule(current, previous /*null when async*/) {
// Simple example: Combine table name, current year, and a sequence number.
function generateUniqueId(tableName) {
var gr = new GlideRecord('sys_number');
gr.addQuery('name', tableName);
gr.query();
if (gr.next()) {
var currentNumber = gr.getValue('number');
gr.number = parseInt(currentNumber) + 1;
gr.update();
return tableName + new Date().getFullYear() + "-" + currentNumber.padStart(5, '0'); // Pad with zeros
}
return null; // Handle case where no number record is found
}
current.u_unique_id = generateUniqueId(current.getTableName()); // Assuming your field is named 'u_unique_id'
})(current, previous);
2. Update User Department:
// (Business Rule - After Update - On sys_user table)
(function executeRule(current, previous /*null when async*/) {
// Update department based on job title (example mapping)
if (current.title.changes() && current.title) { // Check if title changed and is not empty
var title = current.getValue('title');
var department = '';
switch (title.toLowerCase()) {
case 'software engineer':
department = 'Engineering';
break;
case 'project manager':
department = 'Project Management';
break;
case 'hr specialist':
department = 'Human Resources';
break;
// Add more cases as needed
default:
department = 'Other'; // Default department
}
var deptGr = new GlideRecordSecure('cmn_department');
deptGr.addQuery('name', department);
deptGr.query();
if (deptGr.next()){
current.department = deptGr.getUniqueValue();
}
}
})(current, previous);
3. Delete Old Records:
// (Scheduled Job)
(function() {
var cutoffDate = new GlideDateTime();
cutoffDate.addDays(-365); // Delete records older than 1 year
var gr = new GlideRecordSecure('your_table_name'); // Replace with your table name
gr.addQuery('sys_created_on', '<', cutoffDate);
gr.query();
gr.deleteMultiple(); // Use deleteMultiple for bulk deletion (more efficient)
gs.info("Deleted " + gr.getRowCount() + " old records from your_table_name.");
})();
4. High-Priority Incident Notification:
// (Business Rule - After Insert - On incident table)
(function executeRule(current, previous /*null when async*/) {
if (current.priority == 1) { // Assuming priority 1 is "High"
gs.eventQueue('incident.high_priority', current, gs.getUserID(), gs.getUserName());
// Or, use direct email sending:
/*
var email = new GlideEmailOutbound();
email.setSubject('High Priority Incident Created: ' + current.number);
email.setBody('A high-priority incident has been created: ' + current.getLink());
email.addTo('recipient@example.com'); // Replace with recipient
email.send();
*/
}
})(current, previous);
5. Task Assignment:
// (Business Rule - Before Insert/Update - On task table)
(function executeRule(current, previous /*null when async*/) {
// Assign task to a group based on category
if (current.category) { //check if it has category
var category = current.getValue('category');
var assignmentGroup = '';
switch (category) {
case 'software':
assignmentGroup = 'Software Support';
break;
case 'hardware':
assignmentGroup = 'Hardware Support';
break;
// Add more cases
default:
return;
}
var groupGr = new GlideRecordSecure('sys_user_group');
groupGr.addQuery('name', assignmentGroup);
groupGr.query();
if (groupGr.next()){
current.assignment_group = groupGr.getUniqueValue();
}
}
})(current, previous);
6. Form Input Validation:
// (Client Script - OnSubmit - On your custom table)
function onSubmit() {
// Validate that a required field is not empty
if (g_form.getValue('u_my_required_field') == '') {
g_form.addErrorMessage('My Required Field cannot be empty.');
return false; // Prevent form submission
}
// Validate a number field is within a range
var numValue = parseInt(g_form.getValue('u_my_number_field'));
if (isNaN(numValue) || numValue < 1 || numValue > 100) {
g_form.addErrorMessage('My Number Field must be between 1 and 100.');
return false;
}
return true; // Allow submission if all validations pass
}
7. Update User Location:
// (Business Rule - After Update - On cmn_department table OR Scheduled Job)
(function executeRule(current, previous /*null when async*/) {
// Get the location of the department.
var departmentLocation = current.location; // Assuming department has a location
// Update all users in the specified department
var userGr = new GlideRecordSecure('sys_user');
userGr.addQuery('department', current.sys_id);
userGr.query();
while (userGr.next()) {
userGr.location = departmentLocation;
userGr.update(); // Important: Update each user record
}
})(current, previous);
// ALTERNATIVELY: Scheduled Job to run periodically
/*
(function() {
var deptGr = new GlideRecord('cmn_department');
deptGr.addQuery('name', 'Engineering'); // Example department
deptGr.query();
if (deptGr.next()) {
var deptLocation = deptGr.location;
var userGr = new GlideRecord('sys_user');
userGr.addQuery('department', deptGr.sys_id);
userGr.query();
while (userGr.next()) {
userGr.location = deptLocation;
userGr.update();
}
}
})();
*/
8. Close Incidents on Deactivation:
// (Business Rule - Before Update - On sys_user table)
(function executeRule(current, previous /*null when async*/) {
if (current.active.changesTo(false)) { // Check if the user is being deactivated
var incGr = new GlideRecordSecure('incident');
incGr.addQuery('caller_id', current.sys_id);
incGr.addActiveQuery(); // Only open incidents
incGr.query();
while (incGr.next()) {
incGr.incident_state = 7; // Assuming 7 is the "Closed" state value
incGr.comments = 'Incident automatically closed due to user deactivation.';
incGr.update();
}
}
})(current, previous);
9. Export Data to Excel:
// (Background Script - Use with caution, can impact performance)
// Better approach: Use a Scheduled Report or a REST API for large exports.
// This is a simplified example for a small dataset.
(function() {
var gr = new GlideRecordSecure('incident'); // Example: Export incidents
gr.setLimit(100); // Limit the number of records for testing
gr.query();
var data = [];
data.push(['Number', 'Short Description', 'State', 'Opened At']); // Header row
while (gr.next()) {
data.push([
gr.getValue('number'),
gr.getValue('short_description'),
gr.getDisplayValue('incident_state'), // Get display value for choice fields
gr.getValue('opened_at')
]);
}
// In a real scenario, you'd use a library (like SheetJS) to create an Excel file.
// For this example, we'll just log the data in a CSV-like format:
for (var i = 0; i < data.length; i++) {
gs.info(data[i].join(','));
}
})();
10. Calculate Total Incident Cost:
// (Scheduled Job OR Business Rule to update a custom field)
(function() {
var totalCost = 0;
var gr = new GlideRecordSecure('incident');
gr.addActiveQuery(); // Only open incidents
gr.query();
while (gr.next()) {
// Assuming you have a 'u_cost' field on the incident table
totalCost += parseFloat(gr.getValue('u_cost') || 0); // Handle null/empty values
}
gs.info('Total cost of open incidents: ' + totalCost);
// To update a field (e.g., on a custom table to store this value):
/*
var summaryGr = new GlideRecord('u_incident_summary');
summaryGr.get('your_record_sys_id'); // Get the specific record to update
summaryGr.u_total_cost = totalCost;
summaryGr.update();
*/
})();
Advanced GlideRecord Queries
1. Incidents for CI:
var ciSysId = 'your_ci_sys_id'; // Replace with the actual sys_id of the CI
var gr = new GlideRecordSecure('incident');
gr.addQuery('cmdb_ci', ciSysId);
gr.query();
while (gr.next()) {
gs.info('Incident: ' + gr.number);
}
2. Active Users in Domain:
var domain = 'your_domain_name'; // Replace with the domain name
var gr = new GlideRecordSecure('sys_user');
gr.addQuery('sys_domain', domain);
gr.addActiveQuery(); // Only active users
gr.query();
while (gr.next()) {
gs.info('User: ' + gr.user_name);
}
3. Open Incidents for Group:
var groupSysId = 'your_group_sys_id'; // Replace with the group's sys_id
var gr = new GlideRecordSecure('incident');
gr.addQuery('assignment_group', groupSysId);
gr.addActiveQuery();
gr.query();
while (gr.next()) {
gs.info('Incident: ' + gr.number);
}
4. Problems for Incident:
var incidentSysId = 'your_incident_sys_id'; // Replace with the incident's sys_id
var gr = new GlideRecordSecure('problem');
gr.addQuery('rfc', incidentSysId); // Assuming 'rfc' field links to the incident
gr.query();
while (gr.next()) {
gs.info('Problem: ' + gr.number);
}
5. Incidents by Priority and Group:
var priority = 1; // Example: Priority 1
var groupSysId = 'your_group_sys_id';
var gr = new GlideRecordSecure('incident');
gr.addQuery('priority', priority);
gr.addQuery('assignment_group', groupSysId);
gr.query();
while (gr.next()) {
gs.info('Incident: ' + gr.number);
}
6. Changes for Maintenance Window:
var windowStart = new GlideDateTime('2024-03-15 22:00:00'); // Example start time
var windowEnd = new GlideDateTime('2024-03-16 06:00:00'); // Example end time
var gr = new GlideRecordSecure('change_request');
gr.addQuery('start_date', '>=', windowStart);
gr.addQuery('end_date', '<=', windowEnd);
// OR, if you have a dedicated maintenance window table:
// gr.addQuery('maintenance_window', 'your_window_sys_id');
gr.query();
while (gr.next()) {
gs.info('Change: ' + gr.number);
}
7. Open Tasks by Group and Due Date:
var groupSysId = 'your_group_sys_id';
var dueDate = new GlideDateTime('2024-03-20'); // Example due date
var gr = new GlideRecordSecure('task'); // Or a specific task table like 'sc_task'
gr.addQuery('assignment_group', groupSysId);
gr.addQuery('due_date', '<=', dueDate);
gr.addActiveQuery();
gr.query();
while (gr.next()) {
gs.info('Task: ' + gr.number);
}
8. Knowledge Articles by Category:
var categorySysId = 'your_category_sys_id'; // Replace with the category's sys_id
var gr = new GlideRecordSecure('kb_knowledge');
gr.addQuery('kb_category', categorySysId);
gr.query();
while (gr.next()) {
gs.info('Article: ' + gr.short_description);
}
9. Catalog Items by Category and Price:
var categorySysId = 'your_category_sys_id';
var price = 100; // Example price
var gr = new GlideRecordSecure('sc_cat_item');
gr.addQuery('category', categorySysId);
gr.addQuery('price', '<=', price); // Or '>=', '=', etc.
gr.query();
while (gr.next()) {
gs.info('Item: ' + gr.name);
}
10. Users by Department and Job Title:
var departmentSysId = 'your_department_sys_id';
var jobTitle = 'Software Engineer';
var gr = new GlideRecordSecure('sys_user');
gr.addQuery('department', departmentSysId);
gr.addQuery('title', jobTitle);
gr.query();
while (gr.next()) {
gs.info('User: ' + gr.user_name);
}
UI Policies and Client Scripts
1. Short Description Format:
// (UI Policy - On Incident table)
// Condition: (Leave blank to apply to all records)
// Script: Execute if true:
function onCondition() {
g_form.getControl('short_description').style.textTransform = 'uppercase'; // Example: Force uppercase
// Or, use a regular expression to enforce a more complex format
}
2. Client-Side Form Validation: (See example #6 in Basics)
3. Hide/Disable Fields by Role:
// (UI Policy - On your table)
// Condition: gs.hasRole('itil') (Example: Only for ITIL users)
// Script: Execute if true:
function onCondition() {
g_form.setVisible('u_my_field', false); // Hide the field
g_form.setDisabled('u_another_field', true); // Disable the field
}
// Script: Execute if false: (Optional - to show/enable fields for other roles)
function onCondition() {
g_form.setVisible('u_my_field', true);
g_form.setDisabled('u_another_field', false);
}
4. Auto-Populate Fields:
// (Client Script - OnChange - On the field that triggers the auto-population)
function onChange(control, oldValue, newValue, isLoading, isTemplate) {
if (isLoading || newValue === '') {
return;
}
// Example: Auto-populate the 'assigned_to' field based on the 'assignment_group'
if (g_form.getValue('assignment_group') == 'your_group_sys_id') {
g_form.setValue('assigned_to', 'user_sys_id'); // Set to a specific user
}
//Example: Populate the 'location' field based on the 'caller_id'
var caller = g_form.getReference('caller_id', setLocation); // Use getReference for related fields
}
function setLocation(caller) {
if(caller){
g_form.setValue('location', caller.location);
}
}
5. Conditional Mandatory Field:
// (UI Policy - On your table)
// Condition: current.u_my_trigger_field == 'some_value' (Example condition)
// Script: Execute if true:
function onCondition() {
g_form.setMandatory('u_my_dependent_field', true);
}
// Script: Execute if false:
function onCondition() {
g_form.setMandatory('u_my_dependent_field', false);
}
6. Auto-Complete Field:
// (Client Script - OnLoad - On your table)
// Requires creating a Script Include to handle the server-side query.
function onLoad() {
// This is a simplified example. For a robust auto-complete, you'd use
// AJAX and a Script Include to query the server as the user types.
g_form.getElement('u_my_autocomplete_field').setAttribute('autocomplete', 'off'); // Disable browser autocomplete
g_form.getElement('u_my_autocomplete_field').addEventListener('keyup', function(event) {
var input = g_form.getValue('u_my_autocomplete_field');
if (input.length > 2) { // Start suggesting after 2 characters
// Call a Script Include via GlideAjax to get suggestions
var ga = new GlideAjax('MyAutocompleteUtil'); // Replace with your Script Include name
ga.addParam('sysparm_name', 'getSuggestions');
ga.addParam('sysparm_input', input);
ga.getXML(handleSuggestions);
}
});
function handleSuggestions(response) {
var suggestions = response.responseXML.documentElement.getAttribute("answer");
// suggestions will be a comma-separated string of sys_ids (from the Script Include)
// You'd then display these suggestions in a dropdown or similar UI element.
// (This part requires more complex UI manipulation and is beyond a simple example.)
}
}
// --- Script Include: MyAutocompleteUtil ---
// (Client callable: true)
var MyAutocompleteUtil = Class.create();
MyAutocompleteUtil.prototype = Object.extendsObject(AbstractAjaxProcessor, {
getSuggestions: function() {
var input = this.getParameter('sysparm_input');
var suggestions = [];
var gr = new GlideRecordSecure('sys_user'); // Example: Suggest users
gr.addQuery('user_name', 'STARTSWITH', input);
gr.setLimit(10); // Limit the number of suggestions
gr.query();
while (gr.next()) {
suggestions.push(gr.getUniqueValue()); // Add sys_id to the suggestions array
}
return suggestions.join(','); // Return as a comma-separated string
},
type: 'MyAutocompleteUtil'
});
7. Date/Time Format:
// (UI Policy - On your table)
// Condition: (Leave blank to apply to all records)
// Script: Execute if true:
function onCondition() {
//This is usually handled by user preferences, but can be forced with a UI policy
// This does *not* change the underlying data, only the display.
g_form.getControl('your_date_time_field').style.dateFormat = 'yyyy-MM-dd HH:mm:ss'; // Example format
}
8. Unsaved Changes Warning:
// (Client Script - OnLoad - On your table)
function onLoad() {
g_form.enableUnloadConfirm(); // Enable the confirmation dialog
}
9. Show/Hide Sections:
//(UI Policy - On your table)
//Condition: current.u_my_trigger_field == 'some_value'
//Script: Execute if true:
function onCondition() {
g_form.setSectionDisplay('your_section_name', false); // Hide the section
}
//Script: Execute if false:
function onCondition() {
g_form.setSectionDisplay('your_section_name', true); // Show the section
}
10. Update Field Based on Others:
// (Client Script - OnChange - On one of the fields that triggers the update)
function onChange(control, oldValue, newValue, isLoading, isTemplate) {
if (isLoading || newValue === '') {
return;
}
// Example: Calculate a 'total' field based on 'quantity' and 'price'
var quantity = parseInt(g_form.getValue('u_quantity') || 0);
var price = parseFloat(g_form.getValue('u_price') || 0);
var total = quantity * price;
g_form.setValue('u_total', total);
}
Script Includes and Server-Side Scripting
1. Task Due Date Calculation:
// Script Include: TaskDueDateCalculator
// (Client callable: false)
var TaskDueDateCalculator = Class.create();
TaskDueDateCalculator.prototype = {
initialize: function() {
},
calculateDueDate: function(priority, startDate) {
// startDate should be a GlideDateTime object
var dueDate = new GlideDateTime(startDate);
switch (parseInt(priority)) {
case 1: // High
dueDate.addDays(1);
break;
case 2: // Medium
dueDate.addDays(3);
break;
case 3: // Low
dueDate.addDays(7);
break;
default:
dueDate.addDays(7); // Default
}
return dueDate;
},
type: 'TaskDueDateCalculator'
};
// Example usage (in a Business Rule):
/*
(function executeRule(current, previous) {
var calculator = new TaskDueDateCalculator();
var startDate = new GlideDateTime(current.sys_created_on); // Use creation date as start
current.due_date = calculator.calculateDueDate(current.priority, startDate);
})(current, previous);
*/
2. Phone Number Validation/Formatting:
// Script Include: PhoneNumberUtil
// (Client callable: true)
var PhoneNumberUtil = Class.create();
PhoneNumberUtil.prototype = Object.extendsObject(AbstractAjaxProcessor, {
formatPhoneNumber: function(phoneNumber) {
// Basic example: Format as (XXX) XXX-XXXX
var cleaned = ('' + phoneNumber).replace(/\D/g, ''); // Remove non-digits
var match = cleaned.match(/^(\d{3})(\d{3})(\d{4})$/);
if (match) {
return '(' + match[1] + ') ' + match[2] + '-' + match[3];
}
return phoneNumber; // Return original if no match (or handle differently)
},
validatePhoneNumber: function(phoneNumber) {
var cleaned = ('' + phoneNumber).replace(/\D/g, '');
return /^\d{10}$/.test(cleaned); // Example: Validate 10-digit number
},
type: 'PhoneNumberUtil'
});
// Example Client Script usage (OnChange):
/*
function onChange(control, oldValue, newValue, isLoading, isTemplate) {
if (isLoading || newValue === '') {
return;
}
var util = new GlideAjax('PhoneNumberUtil');
util.addParam('sysparm_name', 'formatPhoneNumber');
util.addParam('sysparm_phone', newValue);
util.getXMLAnswer(function(answer) {
g_form.setValue('u_phone_number', answer); // Update the field with the formatted number
});
}
*/
3. Manager Approval Request:
// Script Include: ApprovalUtil
// (Client callable: false)
var ApprovalUtil = Class.create();
ApprovalUtil.prototype = {
initialize: function() {
},
requestManagerApproval: function(recordSysId, tableName) {
var gr = new GlideRecordSecure(tableName);
if (gr.get(recordSysId)) {
var manager = gr.caller_id.manager; // Assuming the record has a 'caller_id' field
if (manager) {
var approval = new GlideRecord('sysapproval_approver');
approval.initialize();
approval.state = 'requested';
approval.sysapproval = recordSysId;
approval.approver = manager;
approval.document_id = recordSysId;
approval.source_table = tableName;
approval.insert();
return true;
}
}
return false;
},
type: 'ApprovalUtil'
};
//Example usage (in a Business Rule):
/*
(function executeRule(current, previous) {
var approvalUtil = new ApprovalUtil();
approvalUtil.requestManagerApproval(current.sys_id, current.getTableName());
})(current, previous);
*/
4. Custom Incident Number:
// Script Include: IncidentNumberUtil
// (Client callable: false)
var IncidentNumberUtil = Class.create();
IncidentNumberUtil.prototype = {
initialize: function() {
},
getNextIncidentNumber: function() {
var prefix = 'INC';
var year = new Date().getFullYear();
var sequenceField = 'u_incident_sequence'; // Custom field to store the sequence
// Get the sequence record (create it if it doesn't exist)
var seqGr = new GlideRecordSecure('u_custom_sequence'); // Or use sys_number table
seqGr.addQuery('u_table_name', 'incident'); // Assuming a field to identify the table
seqGr.query();
var nextSeq;
if (!seqGr.next()) {
seqGr.initialize();
seqGr.u_table_name = 'incident';
seqGr.u_incident_sequence = 1;
seqGr.insert();
nextSeq = 1;
} else {
nextSeq = parseInt(seqGr.getValue(sequenceField)) + 1;
seqGr.setValue(sequenceField, nextSeq);
seqGr.update();
}
return prefix + year + '-' + String(nextSeq).padStart(5, '0'); // INC2024-00001
},
type: 'IncidentNumberUtil'
};
// Example usage (in a Business Rule - Before Insert - On incident table):
/*
(function executeRule(current, previous) {
var util = new IncidentNumberUtil();
current.number = util.getNextIncidentNumber();
})(current, previous);
*/
5. Data Encryption/Decryption:
// Script Include: EncryptionUtil
// (Client callable: false)
// Requires the Encryption Support plugin to be activated.
var EncryptionUtil = Class.create();
EncryptionUtil.prototype = {
initialize: function() {
this.encryptionContext = 'your_encryption_context_sys_id'; // Replace!
},
encryptData: function(plainText) {
if (!plainText) {
return '';
}
var encrypter = new GlideEncrypter();
return encrypter.encrypt(plainText, this.encryptionContext);
},
decryptData: function(encryptedText) {
if (!encryptedText) {
return '';
}
var encrypter = new GlideEncrypter();
return encrypter.decrypt(encryptedText, this.encryptionContext);
},
type: 'EncryptionUtil'
};
// Example usage:
/*
var util = new EncryptionUtil();
var encrypted = util.encryptData('my secret data');
gs.info('Encrypted: ' + encrypted);
var decrypted = util.decryptData(encrypted);
gs.info('Decrypted: ' + decrypted);
*/
6. Unique Record Code: (Similar to #1 in Basics - See that example)
// Script Include: IncidentUtil
// (Client callable: false)
var IncidentUtil = Class.create();
IncidentUtil.prototype = {
initialize: function() {
},
updateRelatedTasks: function(incidentSysId) {
var taskGr = new GlideRecordSecure('task'); // Or a specific task table
taskGr.addQuery('parent', incidentSysId); // Assuming 'parent' field links to the incident
taskGr.addActiveQuery();
taskGr.query();
while (taskGr.next()) {
taskGr.state = 3; // Assuming 3 is the "Closed Complete" state
taskGr.comments = 'Task closed automatically due to incident closure.';
taskGr.update();
}
},
type: 'IncidentUtil'
};
//Example usage (in a Business Rule - After Update - On incident table):
/*
(function executeRule(current, previous) {
if (current.incident_state.changesTo(7)) { // Assuming 7 is "Closed"
var util = new IncidentUtil();
util.updateRelatedTasks(current.sys_id);
}
})(current, previous);
*/
8. Service Catalog Request Cost:
// Script Include: RequestCostCalculator
// (Client callable: false)
var RequestCostCalculator = Class.create();
RequestCostCalculator.prototype = {
initialize: function() {
},
calculateRequestCost: function(requestSysId) {
var totalCost = 0;
var itemGr = new GlideRecordSecure('sc_req_item');
itemGr.addQuery('request', requestSysId);
itemGr.query();
while (itemGr.next()) {
totalCost += parseFloat(itemGr.price || 0) * parseInt(itemGr.quantity || 1);
// Consider options/variables that might affect cost
}
return totalCost;
},
type: 'RequestCostCalculator'
};
//Example usage (in a Business Rule - After Update - On sc_request table):
/*
(function executeRule(current, previous) {
var calculator = new RequestCostCalculator();
current.u_total_cost = calculator.calculateRequestCost(current.sys_id); // Store in a custom field
})(current, previous);
*/
9. Group Users and Manager Info:
// Script Include: GroupInfoUtil
// (Client callable: true/false, depending on how you use it)
var GroupInfoUtil = Class.create();
GroupInfoUtil.prototype = Object.extendsObject(AbstractAjaxProcessor,{
initialize: function() {
},
getGroupMembersAndManagers: function(groupSysId) {
var members = [];
var userGr = new GlideRecordSecure('sys_user_grmember');
userGr.addQuery('group', groupSysId);
userGr.query();
while (userGr.next()) {
var user = userGr.user.getRefRecord(); // Efficiently get the user record
if (user.isValidRecord() && user.active) { //check if its valid and active
var manager = user.manager.getRefRecord();
var managerName = manager.isValidRecord() ? manager.getValue('name') : 'No Manager'; //check if manager is valid
members.push({
user_name: user.getValue('user_name'),
email: user.getValue('email'),
manager: managerName
});
}
}
return members; // Return an array of objects
},
type: 'GroupInfoUtil'
});
// Example usage (can be used in a client script with GlideAjax, or server-side):
/*
// Server-side:
var util = new GroupInfoUtil();
var groupInfo = util.getGroupMembersAndManagers('your_group_sys_id');
for (var i = 0; i < groupInfo.length; i++) {
gs.info('User: ' + groupInfo[i].user_name + ', Manager: ' + groupInfo[i].manager);
}
// Client-side (with GlideAjax):
var ga = new GlideAjax('GroupInfoUtil');
ga.addParam('sysparm_name', 'getGroupMembersAndManagers');
ga.addParam('sysparm_group', g_form.getValue('assignment_group')); // Example
ga.getXMLAnswer(function(answer) {
var members = JSON.parse(answer); // Parse the JSON response
for (var i = 0; i < members.length; i++) {
console.log('User: ' + members[i].user_name + ', Manager: ' + members[i].manager);
}
});
*/
10. Email Notification with Incident Details:
// Script Include: IncidentNotificationUtil
// (Client callable: false)
var IncidentNotificationUtil = Class.create();
IncidentNotificationUtil.prototype = {
initialize: function() {
},
sendIncidentNotification: function(incidentSysId, recipientEmail
No Comments