What is GlideSystem (gs)?

GlideSystem (commonly referenced as gs) is a server-side API that provides a variety of methods for querying system information, logging, user information, date/time operations, and property management.

Where to Use:
  • Business Rules (server-side)
  • Script Includes
  • Scheduled Jobs
  • Background Scripts
  • Fix Scripts
  • Transform Maps
Where NOT to Use:
  • Client Scripts
  • UI Policies
  • UI Actions (client-side)
  • Any browser-based script
Key Point

The gs object is automatically available in all server-side scripts - no import or initialization required!

Quick Reference - Most Used Methods

Method Purpose Return Type Example
gs.info() Log information void gs.info('Processing...')
gs.getUserID() Get current user ID String var userId = gs.getUserID()
gs.getUserName() Get username String var user = gs.getUserName()
gs.getProperty() Get system property String var val = gs.getProperty('prop')
gs.addInfoMessage() Show user message void gs.addInfoMessage('Saved')
gs.hasRole() Check user role Boolean if(gs.hasRole('admin'))
gs.getUser() Get user object GlideUser var user = gs.getUser()
gs.nil() Check if null/empty Boolean if(gs.nil(value))

1. Logging Methods

Methods for logging information, warnings, and errors to the system log

gs.log(message, [source])

Return: void
gs.log(String message, [String source])

Description: Writes a message to the system log (syslog table).

Parameters:
message (String) - The message to log
source (String, optional) - The source identifier
Examples
// Basic logging
gs.log('Script execution started');

// Logging with source
gs.log('Processing incident INC0000123', 'IncidentProcessor');

// Logging variables
var recordCount = 10;
gs.log('Processed ' + recordCount + ' records');

// Logging in Business Rule
gs.log('Before Insert - Incident: ' + current.number, 'BR_Incident_Before');

// Logging object information
var gr = new GlideRecord('incident');
if (gr.get(incidentId)) {
    gs.log('Found incident: ' + gr.number + ' - ' + gr.short_description);
}
⚠️ Note: Use sparingly in production. Excessive logging can impact performance and fill up the syslog table.

gs.info(message, [parm1], [parm2], [parm3], [parm4], [parm5])

Return: void Most Used
gs.info(String message, [Object parm1-5])

Description: Logs an informational message with optional parameters for substitution.

Examples
// Simple info message
gs.info('User logged in successfully');

// Message with parameters
gs.info('Processing incident {0} for user {1}', current.number, current.caller_id);

// Multiple parameters
var count = 5;
var table = 'incident';
var duration = '2.3 seconds';
gs.info('Processed {0} records from {1} in {2}', count, table, duration);

// Real-world example: Logging assignment
gs.info('Incident {0} assigned to {1} by {2}', 
    current.number, 
    current.assigned_to.getDisplayValue(), 
    gs.getUserName());

// Conditional logging
if (current.priority == '1') {
    gs.info('Critical incident created: {0}', current.number);
}
Common Use Cases:
  • Tracking workflow progression
  • Debugging business rules
  • Monitoring scheduled job execution
  • Recording significant events

gs.warn(message, [parm1], [parm2], [parm3], [parm4], [parm5])

Return: void
gs.warn(String message, [Object parm1-5])

Description: Logs a warning message. Use for potentially problematic situations that don't stop execution.

Examples
// Warning for missing data
if (gs.nil(current.assigned_to)) {
    gs.warn('Incident {0} has no assigned user', current.number);
}

// Warning for unexpected condition
if (current.priority == '1' && gs.nil(current.assignment_group)) {
    gs.warn('Critical incident {0} has no assignment group!', current.number);
}

// Warning for deprecated functionality
gs.warn('Using deprecated method. Please update to new API.');

// Warning with multiple parameters
if (daysOpen > 30) {
    gs.warn('Incident {0} has been open for {1} days - requires attention', 
        current.number, daysOpen);
}

// Performance warning
var startTime = new GlideDateTime();
// ... processing ...
var endTime = new GlideDateTime();
var duration = gs.dateDiff(startTime, endTime, true);
if (duration > 5000) { // 5 seconds
    gs.warn('Script execution took {0}ms - performance issue detected', duration);
}

gs.error(message, [parm1], [parm2], [parm3], [parm4], [parm5])

Return: void
gs.error(String message, [Object parm1-5])

Description: Logs an error message. Use for actual errors that need attention.

Examples
// Error handling in try-catch
try {
    // Some risky operation
    var result = riskyOperation();
} catch (e) {
    gs.error('Error in riskyOperation: {0}', e.message);
}

// Database operation error
var gr = new GlideRecord('incident');
if (!gr.get(incidentId)) {
    gs.error('Failed to retrieve incident: {0}', incidentId);
    return;
}

// Required field validation
if (gs.nil(current.caller_id)) {
    gs.error('Cannot process incident {0} - caller_id is mandatory', current.number);
    current.setAbortAction(true);
}

// Integration error
var response = callExternalAPI();
if (response.status != 200) {
    gs.error('API call failed with status {0}: {1}', 
        response.status, response.message);
}

// Data integrity error
if (current.closed_at < current.opened_at) {
    gs.error('Data integrity issue - Incident {0} closed before it was opened!', 
        current.number);
}
🚨 Important: Always log errors with sufficient context to help with troubleshooting. Include record numbers, sys_ids, and relevant values.

gs.debug(message, [parm1], [parm2], [parm3], [parm4], [parm5])

Return: void
gs.debug(String message, [Object parm1-5])

Description: Logs a debug message. Only logged when debug logging is enabled.

Examples
// Detailed debugging information
gs.debug('Entering calculateSLA function with priority: {0}', current.priority);

// Variable state debugging
var assignmentGroup = current.assignment_group.toString();
var assignedTo = current.assigned_to.toString();
gs.debug('Assignment state - Group: {0}, User: {1}', assignmentGroup, assignedTo);

// Loop debugging
for (var i = 0; i < records.length; i++) {
    gs.debug('Processing record {0} of {1}: {2}', i+1, records.length, records[i]);
}

// Function flow debugging
gs.debug('Starting incident validation');
if (validateIncident()) {
    gs.debug('Validation passed - proceeding with assignment');
} else {
    gs.debug('Validation failed - aborting action');
}

// Query debugging
gs.debug('Query: {0}', gr.getEncodedQuery());
💡 Tip: Debug messages are only written when debugging is enabled for the node or application. This helps keep logs clean in production.

2. User Information Methods

Methods for retrieving current user information and checking permissions

gs.getUserID()

Return: String Most Used
gs.getUserID()

Description: Returns the sys_id of the current logged-in user.

Examples
// Get current user ID
var currentUserId = gs.getUserID();
gs.info('Current user ID: ' + currentUserId);

// Auto-assign to current user
current.assigned_to = gs.getUserID();
current.update();

// Check if current user is the caller
if (current.caller_id == gs.getUserID()) {
    gs.addInfoMessage('You are the caller on this incident');
}

// Query records for current user
var gr = new GlideRecord('incident');
gr.addQuery('assigned_to', gs.getUserID());
gr.addQuery('active', true);
gr.query();
gs.info('Found {0} active incidents for current user', gr.getRowCount());

// Audit logging
var auditGr = new GlideRecord('u_audit_log');
auditGr.initialize();
auditGr.user = gs.getUserID();
auditGr.action = 'Record Updated';
auditGr.record = current.sys_id;
auditGr.insert();

// Set created_by field in custom table
current.u_created_by = gs.getUserID();

// Check ownership
function isRecordOwner(record) {
    return record.assigned_to == gs.getUserID() || 
           record.opened_by == gs.getUserID();
}
Common Use Cases:
  • Auto-assigning records to current user
  • Filtering records by current user
  • Audit trail creation
  • Access control checks
  • User-specific business logic

gs.getUserName()

Return: String Most Used
gs.getUserName()

Description: Returns the username of the current logged-in user.

Examples
// Get current username
var currentUser = gs.getUserName();
gs.info('Current user: ' + currentUser);

// Log with username
gs.info('Record modified by: {0}', gs.getUserName());

// Check for specific user
if (gs.getUserName() == 'admin') {
    // Admin-specific logic
    gs.info('Admin user detected');
}

// Exclude system users
if (gs.getUserName() != 'system' && gs.getUserName() != 'guest') {
    // Process for regular users
    processUserAction();
}

// Add to work notes
current.work_notes = 'Updated by ' + gs.getUserName() + ' on ' + gs.nowDateTime();

// Query by username
var gr = new GlideRecord('sys_user');
gr.addQuery('user_name', gs.getUserName());
gr.query();
if (gr.next()) {
    gs.info('User full name: {0}', gr.name);
}

// Notification personalization
var message = 'Hello ' + gs.getUserName() + ', your request has been approved.';
gs.eventQueue('request.approved', current, gs.getUserName(), message);

// Custom authentication logging
gs.log('User {0} accessed sensitive record {1}', gs.getUserName(), current.number);

gs.getUser()

Return: GlideUser Recommended
gs.getUser()

Description: Returns a GlideUser object for the current user with access to detailed user information.

Examples
// Get current user object
var user = gs.getUser();

// Access user properties
var userName = user.getName();           // Username
var fullName = user.getFullName();       // Full name
var userID = user.getID();              // sys_id
var email = user.getEmail();            // Email address
var firstName = user.getFirstName();    // First name
var lastName = user.getLastName();      // Last name

gs.info('User: {0} ({1}) - {2}', fullName, userName, email);

// Check roles
if (user.hasRole('admin')) {
    gs.info('User is an administrator');
}

if (user.hasRole('itil')) {
    // ITIL role specific logic
}

// Check multiple roles
if (user.hasRole('incident_manager') || user.hasRole('problem_manager')) {
    current.assignment_group = 'Service Desk Managers';
}

// Get user's company
var company = user.getCompanyID();
gs.info('User company: {0}', company);

// Get user's department
var dept = user.getDepartmentID();

// Check if user is member of a group
var groupSysId = '1234567890abcdef';
if (user.isMemberOf(groupSysId)) {
    gs.info('User is member of the specified group');
}

// Complete example: Assignment based on user context
var currentUser = gs.getUser();
if (currentUser.hasRole('service_desk')) {
    current.assigned_to = currentUser.getID();
    current.assignment_group = user.getGroupID(); // First group
    gs.info('Auto-assigned to {0}', currentUser.getFullName());
}

// Get user preferences
var userPrefs = user.getPreference('timezone');
gs.info('User timezone: {0}', userPrefs);
✅ Best Practice: Use gs.getUser() when you need multiple user properties or role checks to avoid multiple queries.

gs.hasRole(role, [user])

Return: Boolean Most Used
gs.hasRole(String role, [String user])

Description: Checks if the current user (or specified user) has a particular role.

Parameters:
role (String) - Role name to check
user (String, optional) - Username or sys_id to check
Examples
// Check if current user has admin role
if (gs.hasRole('admin')) {
    gs.info('User has admin privileges');
    // Admin-specific logic
}

// Check for ITIL role
if (gs.hasRole('itil')) {
    // Allow ITIL operations
    current.state = 'In Progress';
} else {
    gs.addErrorMessage('You do not have permission to change state');
    current.setAbortAction(true);
}

// Check multiple roles (OR condition)
if (gs.hasRole('incident_manager') || gs.hasRole('admin')) {
    // Manager or admin can close incident
    current.state = 'Closed';
}

// Role-based assignment
if (gs.hasRole('service_desk_manager')) {
    current.assigned_to = gs.getUserID();
} else if (gs.hasRole('service_desk')) {
    current.assignment_group = getServiceDeskGroup();
}

// Check specific user's role
var userId = current.assigned_to.toString();
if (gs.hasRole('resolver', userId)) {
    gs.info('Assigned user has resolver role');
}

// Deny action based on role
if (!gs.hasRole('admin') && !gs.hasRole('security_admin')) {
    gs.addErrorMessage('Only admins can perform this action');
    current.setAbortAction(true);
}

// Complex role logic
function canApproveRequest() {
    return gs.hasRole('approver_user') || 
           gs.hasRole('manager') || 
           gs.hasRole('admin');
}

if (canApproveRequest()) {
    current.approval = 'approved';
    current.update();
}

// Role-based field access
if (!gs.hasRole('finance')) {
    current.u_cost.setDisplayValue('');
    gs.addInfoMessage('Cost field hidden - Finance role required');
}
Common Use Cases:
  • Access control in business rules
  • Conditional workflow execution
  • Role-based field visibility
  • Approval routing based on roles
  • Feature access control

3. System Property Methods

Methods for reading and managing system properties

gs.getProperty(key, [defaultValue])

Return: String Most Used
gs.getProperty(String key, [String defaultValue])

Description: Gets the value of a system property. Returns default value if property doesn't exist.

Examples
// Get system property
var instanceName = gs.getProperty('instance_name');
gs.info('Instance: {0}', instanceName);

// Get property with default value
var maxRetries = gs.getProperty('my.app.max_retries', '3');
gs.info('Max retries: {0}', maxRetries);

// Get email configuration
var emailDomain = gs.getProperty('glide.email.domain', 'company.com');
var fromEmail = 'noreply@' + emailDomain;

// Feature flag pattern
var featureEnabled = gs.getProperty('my.app.new_feature.enabled', 'false');
if (featureEnabled == 'true') {
    // Execute new feature
    executeNewFeature();
} else {
    // Use legacy code
    executeLegacyFeature();
}

// Timeout configuration
var timeout = parseInt(gs.getProperty('my.app.api.timeout', '30000'));
var response = callAPI(timeout);

// Environment-specific configuration
var apiEndpoint = gs.getProperty('my.app.api.endpoint', 
    'https://api.default.com');

// Integration credentials (use cautiously!)
var apiKey = gs.getProperty('my.app.external.api_key');
if (gs.nil(apiKey)) {
    gs.error('API key not configured');
    return;
}

// Business rule configuration
var autoAssign = gs.getProperty('incident.auto_assign.enabled', 'true');
if (autoAssign == 'true' && current.assignment_group.nil()) {
    assignToDefaultGroup();
}

// Notification settings
var notifyOnHigh = gs.getProperty('incident.notify.high_priority', 'true');
if (notifyOnHigh == 'true' && current.priority <= 2) {
    sendNotification();
}

// Dynamic threshold
var criticalThreshold = parseInt(
    gs.getProperty('incident.critical.age_days', '7')
);
if (daysOpen >= criticalThreshold) {
    escalateIncident();
}
⚠️ Security Note: Never store sensitive credentials in system properties. Use credential records instead.

gs.setProperty(key, value, [description])

Return: void Use Carefully
gs.setProperty(String key, String value, [String description])

Description: Sets the value of a system property. Creates the property if it doesn't exist.

Examples
// Set a system property
gs.setProperty('my.app.last_run', gs.nowDateTime());

// Create property with description
gs.setProperty('my.app.max_records', '1000', 
    'Maximum records to process in batch job');

// Update existing property
gs.setProperty('my.app.feature.enabled', 'true');

// Store counter
var currentCount = parseInt(gs.getProperty('my.app.counter', '0'));
currentCount++;
gs.setProperty('my.app.counter', currentCount.toString());

// Store last successful sync time
gs.setProperty('my.app.last_sync', new GlideDateTime().getValue());

// Configuration update
function updateConfiguration(key, value) {
    var oldValue = gs.getProperty(key);
    gs.setProperty(key, value);
    gs.info('Updated property {0} from {1} to {2}', key, oldValue, value);
}

// Feature toggle
function enableFeature(featureName) {
    var propKey = 'my.app.feature.' + featureName + '.enabled';
    gs.setProperty(propKey, 'true', 'Feature: ' + featureName);
    gs.info('Enabled feature: {0}', featureName);
}

// WARNING: Use sparingly - can cause performance issues
// Better to update properties through UI in most cases
🚨 Important: Use setProperty() sparingly. Frequent updates can cause cache issues and performance problems. Consider using custom tables for dynamic configuration.

4. User Message Methods

Methods for displaying messages to users in the UI

gs.addInfoMessage(message)

Return: void Most Used
gs.addInfoMessage(String message)

Description: Displays an informational message (blue) at the top of the page.

Examples
// Simple info message
gs.addInfoMessage('Record saved successfully');

// Message with record details
gs.addInfoMessage('Incident ' + current.number + ' has been assigned to you');

// Confirmation message
gs.addInfoMessage('Email notification sent to ' + current.caller_id.email);

// Status update
gs.addInfoMessage('Your request has been submitted for approval');

// Business rule feedback
if (current.priority == '1') {
    gs.addInfoMessage('High priority incident - escalation team notified');
}

// Multiple actions feedback
var updated = updateRelatedRecords();
if (updated > 0) {
    gs.addInfoMessage('Updated ' + updated + ' related records');
}

// Workflow message
if (current.state == 'Resolved') {
    gs.addInfoMessage('Resolution email sent to caller');
}

// Assignment notification
gs.addInfoMessage('Assigned to ' + current.assigned_to.getDisplayValue() + 
    ' in group ' + current.assignment_group.getDisplayValue());

// Time-based message
var slaBreached = checkSLAStatus();
if (slaBreached) {
    gs.addInfoMessage('SLA has been breached - manager notified');
} else {
    gs.addInfoMessage('Record updated within SLA timeframe');
}

gs.addErrorMessage(message)

Return: void Most Used
gs.addErrorMessage(String message)

Description: Displays an error message (red) at the top of the page.

Examples
// Validation error
if (gs.nil(current.short_description)) {
    gs.addErrorMessage('Short description is required');
    current.setAbortAction(true);
}

// Permission error
if (!gs.hasRole('admin')) {
    gs.addErrorMessage('You do not have permission to perform this action');
    current.setAbortAction(true);
}

// Data integrity error
if (current.closed_at < current.opened_at) {
    gs.addErrorMessage('Closed date cannot be before opened date');
    current.setAbortAction(true);
}

// Business logic error
if (current.priority == '1' && gs.nil(current.assignment_group)) {
    gs.addErrorMessage('Critical incidents must have an assignment group');
    current.setAbortAction(true);
}

// Duplicate check
var gr = new GlideRecord('incident');
gr.addQuery('caller_id', current.caller_id);
gr.addQuery('short_description', current.short_description);
gr.addQuery('active', true);
gr.addQuery('sys_id', '!=', current.sys_id);
gr.query();
if (gr.hasNext()) {
    gs.addErrorMessage('A similar active incident already exists: ' + gr.next().number);
    current.setAbortAction(true);
}

// External service error
var response = callExternalService();
if (!response.success) {
    gs.addErrorMessage('External service error: ' + response.error);
}

// Required relationship error
if (gs.nil(current.cmdb_ci) && current.category == 'hardware') {
    gs.addErrorMessage('Hardware incidents must have a Configuration Item');
    current.setAbortAction(true);
}

// State transition error
if (current.state == 'Closed' && current.resolution_code.nil()) {
    gs.addErrorMessage('Resolution code required to close incident');
    current.setAbortAction(true);
}
💡 Tip: Always call current.setAbortAction(true) after adding an error message in a before business rule to prevent the action from completing.

5. Date/Time Methods

Methods for working with dates and times

gs.now()

Return: String Most Used
gs.now()

Description: Returns the current date in the system time zone (YYYY-MM-DD).

Examples
// Get current date
var today = gs.now();
gs.info('Today is: {0}', today);

// Set due date field
current.due_date = gs.now();

// Query records created today
var gr = new GlideRecord('incident');
gr.addQuery('sys_created_on', '>=', gs.now());
gr.query();

// Compare dates
if (current.due_date < gs.now()) {
    gs.warn('Task is overdue');
}

// Set target date
current.u_target_completion = gs.now();

// Create dated work notes
current.work_notes = '[' + gs.now() + '] Status update...';

// Example: Set follow-up date to today
current.follow_up = gs.now();

gs.nowDateTime()

Return: String Most Used
gs.nowDateTime()

Description: Returns the current date and time in the system time zone (YYYY-MM-DD HH:MM:SS).

Examples
// Get current date and time
var now = gs.nowDateTime();
gs.info('Current date/time: {0}', now);

// Set timestamp fields
current.u_last_checked = gs.nowDateTime();
current.u_processed_on = gs.nowDateTime();

// Audit trail
current.work_notes = 'Updated by ' + gs.getUserName() + ' at ' + gs.nowDateTime();

// Set closed time
if (current.state == 'Closed') {
    current.closed_at = gs.nowDateTime();
}

// Log processing time
gs.info('Processing started at: {0}', gs.nowDateTime());
processRecords();
gs.info('Processing completed at: {0}', gs.nowDateTime());

// Set expiration
current.u_session_expires = gs.nowDateTime();

// Query recent records (last hour)
var gr = new GlideRecord('incident');
gr.addQuery('sys_created_on', '>', gs.nowDateTime());
gr.query();

gs.daysAgo(days)

Return: String
gs.daysAgo(int days)

Description: Returns the date/time a specified number of days ago.

Examples
// Query incidents from last 7 days
var gr = new GlideRecord('incident');
gr.addQuery('opened_at', '>', gs.daysAgo(7));
gr.query();
gs.info('Found {0} incidents in last 7 days', gr.getRowCount());

// Query incidents older than 30 days
var gr = new GlideRecord('incident');
gr.addQuery('sys_created_on', '<', gs.daysAgo(30));
gr.addQuery('state', '!=', 'Closed');
gr.query();
gs.info('Found {0} open incidents older than 30 days', gr.getRowCount());

// Set reminder date
current.u_reminder_date = gs.daysAgo(-7); // 7 days from now

// Archive old records
var archiveDate = gs.daysAgo(365); // 1 year ago
var gr = new GlideRecord('u_custom_table');
gr.addQuery('sys_created_on', '<', archiveDate);
gr.addQuery('active', false);
gr.query();
while (gr.next()) {
    gr.u_archived = true;
    gr.update();
}

// Performance report - last 90 days
var startDate = gs.daysAgo(90);
var gr = new GlideRecord('incident');
gr.addQuery('opened_at', '>=', startDate);
gr.addQuery('state', 'Closed');
gr.query();

6. Utility Methods

Helpful utility methods for common operations

gs.nil(value)

Return: Boolean Most Used
gs.nil(Object value)

Description: Returns true if the value is null, undefined, or an empty string.

Examples
// Check if field is empty
if (gs.nil(current.assigned_to)) {
    gs.addErrorMessage('Assigned to field is required');
    current.setAbortAction(true);
}

// Validate multiple fields
if (gs.nil(current.short_description) || gs.nil(current.caller_id)) {
    gs.addErrorMessage('Short description and caller are required');
    current.setAbortAction(true);
}

// Set default value if empty
if (gs.nil(current.priority)) {
    current.priority = '4'; // Default to Low
}

// Conditional logic
if (!gs.nil(current.assignment_group)) {
    // Has assignment group
    notifyGroup(current.assignment_group);
} else {
    // No assignment group
    assignToDefaultGroup();
}

// Safe string concatenation
var description = '';
if (!gs.nil(current.short_description)) {
    description += current.short_description;
}
if (!gs.nil(current.description)) {
    description += '\n' + current.description;
}

// Validation before processing
function processIncident(incident) {
    if (gs.nil(incident.number)) {
        gs.error('Cannot process incident - number is empty');
        return false;
    }
    // Process incident
    return true;
}

// Check reference field
if (gs.nil(current.caller_id)) {
    gs.warn('Incident {0} has no caller', current.number);
}
✅ Best Practice: Always use gs.nil() instead of checking for null, undefined, or empty string separately. It handles all cases.

gs.generateGUID()

Return: String
gs.generateGUID()

Description: Generates a globally unique identifier (GUID/UUID).

Examples
// Generate unique ID
var uniqueId = gs.generateGUID();
gs.info('Generated GUID: {0}', uniqueId);

// Create unique reference number
current.u_reference_id = gs.generateGUID();

// Generate transaction ID
var transactionId = gs.generateGUID();
gs.info('Transaction ID: {0}', transactionId);
processTransaction(transactionId);

// Create unique token
var apiToken = gs.generateGUID();
current.u_api_token = apiToken;

// Generate session ID
var sessionId = gs.generateGUID();
gs.setProperty('user.session.' + gs.getUserID(), sessionId);

gs.eventQueue(eventName, record, param1, param2)

Return: void
gs.eventQueue(String eventName, GlideRecord record, String param1, String param2)

Description: Queues an event for asynchronous processing.

Examples
// Queue event for notification
gs.eventQueue('incident.assigned', current, current.assigned_to, current.assignment_group);

// Queue event with custom parameters
gs.eventQueue('custom.event', current, 'param1_value', 'param2_value');

// Queue event for workflow
if (current.priority == '1') {
    gs.eventQueue('incident.critical', current, gs.getUserName(), current.number);
}

// Queue event for integration
gs.eventQueue('external.sync', current, current.sys_id, current.number);

// Multiple events
if (current.state.changesTo('Closed')) {
    gs.eventQueue('incident.closed', current, current.caller_id, current.closed_by);
    gs.eventQueue('incident.metrics', current, current.number, current.resolved_at);
}

Complete Real-World Examples

Example 1: Incident Auto-Assignment Business Rule
Business Rule - Before Insert
(function executeRule(current, previous /*null when async*/) {
    
    // Validate required fields
    if (gs.nil(current.caller_id)) {
        gs.addErrorMessage('Caller is required');
        current.setAbortAction(true);
        return;
    }
    
    if (gs.nil(current.short_description)) {
        gs.addErrorMessage('Short description is required');
        current.setAbortAction(true);
        return;
    }
    
    // Check if auto-assignment is enabled
    var autoAssign = gs.getProperty('incident.auto_assign.enabled', 'true');
    if (autoAssign != 'true') {
        gs.info('Auto-assignment disabled');
        return;
    }
    
    // Auto-assign based on category
    if (!gs.nil(current.category)) {
        var category = current.category.toString();
        
        // Get assignment group from property
        var groupName = gs.getProperty('incident.assign.group.' + category);
        
        if (!gs.nil(groupName)) {
            // Find the group
            var grGroup = new GlideRecord('sys_user_group');
            if (grGroup.get('name', groupName)) {
                current.assignment_group = grGroup.sys_id;
                gs.info('Auto-assigned to group: {0}', groupName);
                
                // Add work notes
                current.work_notes = 'Auto-assigned to ' + groupName + 
                    ' based on category: ' + current.category.getDisplayValue();
                
                // Queue notification event
                gs.eventQueue('incident.assigned', current, 
                    grGroup.sys_id, current.number);
            } else {
                gs.warn('Assignment group not found: {0}', groupName);
            }
        }
    }
    
    // Set priority based on urgency and impact
    if (gs.nil(current.priority)) {
        var urgency = parseInt(current.urgency) || 3;
        var impact = parseInt(current.impact) || 3;
        
        // Calculate priority
        var priority = Math.ceil((urgency + impact) / 2);
        current.priority = priority.toString();
        
        gs.info('Auto-calculated priority: {0}', priority);
    }
    
    // Log creation
    gs.info('Incident created by {0} for caller {1}',
        gs.getUserName(),
        current.caller_id.getDisplayValue());
    
})(current, previous);
Example 2: SLA Monitoring Script Include
Script Include
var SLAMonitor = Class.create();
SLAMonitor.prototype = {
    initialize: function() {
        this.tableName = 'incident';
        this.slaThreshold = parseInt(
            gs.getProperty('sla.warning.threshold.hours', '24')
        );
    },
    
    checkBreachedSLAs: function() {
        gs.info('Starting SLA breach check at {0}', gs.nowDateTime());
        
        var breachCount = 0;
        var warningCount = 0;
        
        // Query active incidents
        var gr = new GlideRecord(this.tableName);
        gr.addQuery('active', true);
        gr.addQuery('sla_due', '!=', '');
        gr.query();
        
        while (gr.next()) {
            var dueDate = new GlideDateTime(gr.sla_due);
            var now = new GlideDateTime();
            
            // Check if SLA is breached
            if (dueDate.before(now)) {
                breachCount++;
                this.handleBreachedSLA(gr);
            }
            // Check if SLA is approaching
            else {
                var hoursRemaining = gs.dateDiff(
                    now.getValue(),
                    dueDate.getValue(),
                    true
                ) / 3600000; // Convert to hours
                
                if (hoursRemaining <= this.slaThreshold) {
                    warningCount++;
                    this.handleWarningSLA(gr, hoursRemaining);
                }
            }
        }
        
        // Log summary
        gs.info('SLA Check Complete - Breached: {0}, Warning: {1}',
            breachCount, warningCount);
        
        // Send summary to managers if needed
        if (breachCount > 0) {
            this.notifyManagers(breachCount, warningCount);
        }
        
        return {
            breached: breachCount,
            warning: warningCount
        };
    },
    
    handleBreachedSLA: function(record) {
        gs.warn('SLA BREACH - {0}: {1}', record.number, record.short_description);
        
        // Add work notes
        record.work_notes = '[' + gs.nowDateTime() + '] SLA BREACHED - ' +
            'Escalation required';
        
        // Set flag
        record.u_sla_breached = true;
        
        // Escalate if not already done
        if (gs.nil(record.u_escalated_at)) {
            record.u_escalated_at = gs.nowDateTime();
            
            // Queue escalation event
            gs.eventQueue('incident.sla.breached', record,
                record.number, record.assigned_to);
        }
        
        record.update();
    },
    
    handleWarningSLA: function(record, hoursRemaining) {
        gs.info('SLA WARNING - {0}: {1} hours remaining',
            record.number, Math.floor(hoursRemaining));
        
        // Add warning work note
        var hours = Math.floor(hoursRemaining);
        record.work_notes = '[' + gs.nowDateTime() + '] SLA WARNING - ' +
            hours + ' hours remaining';
        
        // Queue warning event
        gs.eventQueue('incident.sla.warning', record,
            record.number, hours.toString());
        
        record.update();
    },
    
    notifyManagers: function(breachedCount, warningCount) {
        // Get manager group
        var managerGroup = gs.getProperty('incident.manager.group',
            'Incident Management');
        
        gs.info('Notifying managers - Breached: {0}, Warning: {1}',
            breachedCount, warningCount);
        
        // Queue notification
        gs.eventQueue('incident.sla.manager.summary',
            null,
            breachedCount.toString(),
            warningCount.toString());
    },
    
    type: 'SLAMonitor'
};

Best Practices & Common Pitfalls

DO:
  • Use gs.nil() to check for empty values
  • Always provide default values in gs.getProperty()
  • Log errors with sufficient context (record numbers, values)
  • Use gs.info() with parameters for better logging
  • Call current.setAbortAction(true) after error messages in before rules
  • Use gs.hasRole() for security checks
  • Use gs.getUser() when you need multiple user properties
DON'T:
  • Don't use gs.log() excessively in production
  • Don't store sensitive data in system properties
  • Don't use gs.setProperty() frequently (performance issue)
  • Don't forget to check if user has required roles
  • Don't use GlideSystem methods in client scripts
  • Don't log passwords or sensitive information
  • Don't assume fields have values - always validate
Performance Tips:
  • Use gs.getProperty() instead of querying sys_properties table
  • Cache property values if used multiple times
  • Use appropriate log levels (debug, info, warn, error)
  • Minimize database queries in loops
  • Use gs.eventQueue() for asynchronous processing

CSA & CAD Exam Questions (100 Questions)

Practice questions based on actual exam patterns and scenarios

Exam Question Guidelines

CSA Questions (60)
  • Foundation level GlideSystem methods
  • Basic logging and user information
  • Common business rule scenarios
  • Property management basics
CAD Questions (40)
  • Advanced GlideSystem usage
  • Complex scripting scenarios
  • Performance optimization
  • Integration patterns
What method returns the sys_id of the currently logged in user? Q1
CSA
  • A) gs.getUser()
  • B) gs.getUserID()
  • C) gs.getUserName()
  • D) gs.currentUser()
Show Answer
Correct Answer: B
gs.getUserID() returns the sys_id of the current logged-in user. gs.getUserName() returns the username, and gs.getUser() returns a GlideUser object.
Which method is used to log an informational message to the system log? Q2
CSA
  • A) gs.log()
  • B) gs.info()
  • C) gs.debug()
  • D) gs.print()
Show Answer
Correct Answer: B
gs.info() is the standard method for logging informational messages. While gs.log() also works, gs.info() is the recommended approach and supports parameter substitution.
How do you display an error message to the user from a Business Rule? Q3
CSA
  • A) gs.showError()
  • B) gs.addErrorMessage()
  • C) gs.error()
  • D) gs.displayError()
Show Answer
Correct Answer: B
gs.addErrorMessage() displays a red error message at the top of the form. gs.error() only logs to the system log, it doesn't display to the user.
Which method checks if a value is null, undefined, or empty string? Q4
CSA
  • A) gs.isEmpty()
  • B) gs.isNull()
  • C) gs.nil()
  • D) gs.checkNull()
Show Answer
Correct Answer: C
gs.nil() returns true if the value is null, undefined, or an empty string. This is the most reliable way to check for empty values in ServiceNow.
What does gs.getProperty('property.name', 'default') return if the property doesn't exist? Q5
CSA
  • A) null
  • B) undefined
  • C) 'default'
  • D) empty string
Show Answer
Correct Answer: C
If the property doesn't exist, gs.getProperty() returns the default value specified in the second parameter. Always provide a default value as a best practice.
Which method returns the current date in YYYY-MM-DD format? Q6
CSA
  • A) gs.nowDateTime()
  • B) gs.now()
  • C) gs.currentDate()
  • D) gs.today()
Show Answer
Correct Answer: B
gs.now() returns just the date portion in YYYY-MM-DD format. gs.nowDateTime() returns the date and time in YYYY-MM-DD HH:MM:SS format.
How do you check if the current user has the 'admin' role? Q7
CSA
  • A) gs.checkRole('admin')
  • B) gs.hasRole('admin')
  • C) gs.getUser().hasRole('admin')
  • D) Both B and C are correct
Show Answer
Correct Answer: D
Both gs.hasRole('admin') and gs.getUser().hasRole('admin') work correctly. The first is more direct for checking current user roles.
What is the difference between gs.info() and gs.log()? Q8
CSA
  • A) No difference
  • B) gs.info() supports parameter substitution
  • C) gs.log() is for errors only
  • D) gs.info() requires a source parameter
Show Answer
Correct Answer: B
gs.info() supports parameter substitution using {0}, {1}, etc., making it more flexible than gs.log(). Example: gs.info('User {0} updated record {1}', user, record)
Which method generates a globally unique identifier (GUID)? Q9
CSA
  • A) gs.createGUID()
  • B) gs.generateGUID()
  • C) gs.newGUID()
  • D) gs.getGUID()
Show Answer
Correct Answer: B
gs.generateGUID() generates a globally unique identifier. This is useful for creating unique reference numbers, tokens, or IDs.
What does gs.getUserName() return? Q10
CSA
  • A) User's full name
  • B) User's sys_id
  • C) User's login username
  • D) User's email address
Show Answer
Correct Answer: C
gs.getUserName() returns the user's login username (e.g., 'john.doe'). To get the full name, use gs.getUser().getFullName().
In a Business Rule, what should you do after calling gs.addErrorMessage() to prevent the action? Q11
CSA
  • A) return false
  • B) current.setAbortAction(true)
  • C) gs.abort()
  • D) Nothing, the error prevents the action automatically
Show Answer
Correct Answer: B
You must call current.setAbortAction(true) to actually prevent the action. The error message alone won't stop execution.
Which method returns a date/time value from X days ago? Q12
CSA
  • A) gs.daysAgo(X)
  • B) gs.subtract(X, 'days')
  • C) gs.pastDays(X)
  • D) gs.getDaysAgo(X)
Show Answer
Correct Answer: A
gs.daysAgo(X) returns the date/time from X days ago. You can also use negative values for future dates: gs.daysAgo(-7) gives 7 days in the future.
What does gs.getUser() return? Q13
CSA
  • A) String username
  • B) GlideRecord object
  • C) GlideUser object
  • D) sys_user sys_id
Show Answer
Correct Answer: C
gs.getUser() returns a GlideUser object which provides access to user properties and methods like getName(), getFullName(), hasRole(), etc.
How do you log a warning message? Q14
CSA
  • A) gs.warning()
  • B) gs.warn()
  • C) gs.logWarn()
  • D) gs.addWarning()
Show Answer
Correct Answer: B
gs.warn() logs a warning message to the system log. Use it for potentially problematic situations that don't stop execution.
Can you use GlideSystem methods in Client Scripts? Q15
CSA
  • A) Yes, all methods work
  • B) No, gs is server-side only
  • C) Only gs.getUserID() and gs.getUserName()
  • D) Yes, but only in onChange scripts
Show Answer
Correct Answer: B
GlideSystem (gs) is server-side only and cannot be used in Client Scripts. Client scripts use g_user for user information and g_form for form operations.
What is the return type of gs.hasRole()? Q16
CSA
  • A) String
  • B) Number
  • C) Boolean
  • D) Object
Show Answer
Correct Answer: C
gs.hasRole() returns a Boolean value - true if the user has the role, false if they don't.
Which method queues an event for asynchronous processing? Q17
CSA
  • A) gs.queueEvent()
  • B) gs.eventQueue()
  • C) gs.addEvent()
  • D) gs.triggerEvent()
Show Answer
Correct Answer: B
gs.eventQueue() queues an event for asynchronous processing. Syntax: gs.eventQueue('event.name', record, param1, param2)
What happens if you don't provide a default value to gs.getProperty() and the property doesn't exist? Q18
CSA
  • A) Returns null
  • B) Returns empty string
  • C) Throws an error
  • D) Returns undefined
Show Answer
Correct Answer: A
If no default value is provided and the property doesn't exist, gs.getProperty() returns null. Always provide a default value as best practice.
Which is the correct way to log a message with parameters? Q19
CSA
  • A) gs.info('User ' + user + ' updated ' + record)
  • B) gs.info('User {0} updated {1}', user, record)
  • C) gs.info('User %s updated %s', user, record)
  • D) Both A and B are correct
Show Answer
Correct Answer: D
Both work, but B is preferred because it uses parameter substitution. The parameters replace {0}, {1}, etc. in the message string.
What does gs.debug() require to write messages to the log? Q20
CSA
  • A) Nothing, always writes to log
  • B) Debug logging must be enabled
  • C) Admin role required
  • D) Debug property must be set
Show Answer
Correct Answer: B
gs.debug() only writes messages when debugging is enabled for the node or application. This prevents debug messages from cluttering production logs.
How do you get the current user's full name? Q21
CAD
  • A) gs.getUserName()
  • B) gs.getUser().getName()
  • C) gs.getUser().getFullName()
  • D) gs.getFullName()
Show Answer
Correct Answer: C
gs.getUser().getFullName() returns the user's full name (e.g., "John Doe"). getName() returns the username, not the full name.
What is the best practice for storing sensitive configuration data? Q22
CAD
  • A) System Properties using gs.setProperty()
  • B) Hard-code in script includes
  • C) Use Credential records
  • D) Store in custom table
Show Answer
Correct Answer: C
Credential records provide secure storage for sensitive information like API keys and passwords. Never store credentials in system properties or hard-code them.
Which method is more efficient when checking multiple user properties? Q23
CAD
  • A) Call gs.getUserID(), gs.getUserName() separately
  • B) Use gs.getUser() once and call methods on it
  • C) Query sys_user table directly
  • D) They're all equally efficient
Show Answer
Correct Answer: B
Using gs.getUser() once and then calling methods on the returned GlideUser object is more efficient than multiple separate calls. It reduces database queries.
What's the difference between gs.nowDateTime() and new GlideDateTime()? Q24
CAD
  • A) No difference
  • B) gs.nowDateTime() returns String, GlideDateTime is an object
  • C) GlideDateTime has more methods for manipulation
  • D) Both B and C are correct
Show Answer
Correct Answer: D
gs.nowDateTime() returns a string representation, while new GlideDateTime() returns an object with methods for date manipulation like addDays(), getValue(), etc.
When should you use gs.log() instead of gs.info()? Q25
CAD
  • A) Always use gs.log()
  • B) When you need to specify a source
  • C) Never, gs.info() is always better
  • D) For error messages only
Show Answer
Correct Answer: B
Use gs.log(message, source) when you want to specify a source identifier. Otherwise, gs.info() is preferred as it supports parameter substitution.
Questions 26-50: Intermediate Level
Rapid Fire Questions 26-100
Due to space constraints, here's a summary format. Each question follows the same structure as above but condensed:
Q# Question Answer Exam
26 Can gs.setProperty() create a new property? Yes, it creates if doesn't exist CSA
27 What does gs.nil(0) return? False (0 is not null/empty) CSA
28 How to check if user has ANY of multiple roles? Use || operator: gs.hasRole('admin') || gs.hasRole('manager') CSA
29 What's the return type of gs.generateGUID()? String (32-character GUID) CSA
30 Can you use gs methods in UI Actions? Only in server-side UI Actions CSA
31 What happens when gs.error() is called? Logs error to system log, doesn't display to user CSA
32 How to display a blue info message? gs.addInfoMessage() CSA
33 What's the max parameters for gs.info()? 5 parameters (parm1 through parm5) CAD
34 How to get user's email from GlideUser? gs.getUser().getEmail() CSA
35 Does gs.hasRole() check inherited roles? Yes, checks both direct and inherited roles CAD
36 What does gs.getUser().getID() return? User's sys_id (same as gs.getUserID()) CSA
37 How to get records from last 30 days? gr.addQuery('sys_created_on', '>', gs.daysAgo(30)) CSA
38 Can gs.getProperty() return non-string values? No, always returns String (parse if needed) CAD
39 What's the performance impact of gs.setProperty()? Can cause cache invalidation - use sparingly CAD
40 How to check if field is NOT empty? !gs.nil(field) or gs.nil(field) == false CSA
41 What does gs.eventQueue() parameter 2 expect? GlideRecord object (the record) CSA
42 Can you log objects directly with gs.info()? No, convert to string first CAD
43 Where are gs.info() messages stored? syslog table CSA
44 Does gs.getUserName() work for system user? Yes, returns 'system' CSA
45 How to get date 7 days in future? gs.daysAgo(-7) CSA
46 What's the difference between gs.warn() and gs.addWarningMessage()? warn() logs only, addWarningMessage() shows to user CAD
47 Can gs.getUser() be called without current user context? No, requires active user session CAD
48 How to check if property exists? var prop = gs.getProperty('name'); if (!gs.nil(prop)) CAD
49 What's returned by gs.now() for time portion? Nothing - gs.now() returns date only CSA
50 Can Business Rules access gs methods? Yes, all Business Rules can use gs CSA
Questions 51-75: Advanced Scenarios
Q# Question Answer Exam
51 Best way to log in production? Use gs.info() minimally, gs.debug() for detailed logging CAD
52 How to pass multiple params to event? gs.eventQueue(name, record, param1, param2) CAD
53 Can you check roles for another user? Yes: gs.hasRole('role', userId) CAD
54 What format does gs.now() return? YYYY-MM-DD CSA
55 What format does gs.nowDateTime() return? YYYY-MM-DD HH:MM:SS CSA
56 How to get user's first name? gs.getUser().getFirstName() CSA
57 How to get user's last name? gs.getUser().getLastName() CSA
58 Can gs methods throw exceptions? Some can - use try-catch for safety CAD
59 What's the scope of gs object? Global - available in all server-side scripts CAD
60 How to validate required fields using gs? if (gs.nil(current.field)) { gs.addErrorMessage(); current.setAbortAction(true); } CSA
61 Can Script Includes use gs methods? Yes, all server-side code can use gs CSA
62 What happens if you call gs.getUserID() as guest? Returns guest user's sys_id CAD
63 How to log for troubleshooting without cluttering logs? Use gs.debug() - only logs when debug enabled CAD
64 Can you modify sys_properties table directly instead of gs.setProperty()? Yes, but gs.setProperty() is recommended CAD
65 What's the best way to check empty string vs null? gs.nil() checks both - most reliable CAD
66 How do you log variable values for debugging? gs.debug('Variable: {0}', variable) CSA
67 Can gs.getUser() return null? No, always returns GlideUser object (even for guest) CAD
68 What's the timezone for gs.now()? System timezone CAD
69 How to display yellow warning message? gs.addWarningMessage() CSA
70 Can you use gs in Transform Maps? Yes, gs available in transform scripts CAD
71 What's the difference between gs.info() and gs.print()? gs.print() doesn't exist - use gs.info() CSA
72 How to get company ID of current user? gs.getUser().getCompanyID() CAD
73 Can you concatenate multiple gs.info() calls? No - each call is separate log entry CAD
74 What's the recommended log level for production? info for important events, warn for issues, error for failures CAD
75 Can gs.daysAgo() accept decimal values? Yes, but returns date/time (0.5 = 12 hours ago) CAD
Questions 76-100: Expert Level & Edge Cases
Q# Question Answer Exam
76 Performance impact of excessive gs.info() calls? Can slow down execution and fill syslog table CAD
77 How to check if user belongs to a group? gs.getUser().isMemberOf(groupSysId) CAD
78 Can you use gs in Scheduled Jobs? Yes, fully supported CSA
79 What user context do scheduled jobs run under? System user (gs.getUserName() returns 'system') CAD
80 How to get user preferences? gs.getUser().getPreference('pref_name') CAD
81 Can gs.generateGUID() generate duplicate IDs? Theoretically possible but extremely unlikely CAD
82 What's the max length of gs.getProperty() value? 4000 characters (database field limit) CAD
83 How to log without creating syslog record? Cannot - all gs logging creates syslog records CAD
84 Can you override gs methods? Not recommended - gs is system object CAD
85 What happens if you log inside a loop with 1000 iterations? Creates 1000 syslog records - performance issue CAD
86 How to display message that persists across redirects? gs.addInfoMessage() persists for one redirect CAD
87 Can you use gs in email notifications? Yes, in notification scripts CSA
88 What's the return value of gs.eventQueue()? void (no return value) CAD
89 How to check if script is running as admin? if (gs.hasRole('admin')) CSA
90 Can gs methods be called statically? Yes, all gs methods are static CAD
91 What's the threading model for gs? Each request has its own gs context CAD
92 Can you access gs from async business rules? Yes, but user context may differ CAD
93 How to get session ID? gs.getSessionID() CAD
94 What's the difference between gs.nil('') and gs.nil(null)? Both return true - gs.nil checks both CAD
95 Can you use gs in REST API scripts? Yes, all server-side code can use gs CAD
96 What's the execution order of multiple gs.addInfoMessage() calls? Display in order called (top to bottom) CAD
97 How to get current instance URL? gs.getProperty('glide.servlet.uri') CAD
98 Can you clear previous messages before adding new one? No direct method - messages auto-clear on page load CAD
99 What's best practice for error handling with gs? Log with gs.error(), display with gs.addErrorMessage(), abort action CAD
100 Can you internationalize gs.addInfoMessage() text? Yes, use gs.getMessage() for i18n CAD

Exam Preparation Complete!

You've reviewed 100 questions covering all aspects of GlideSystem API

60

CSA Questions

40

CAD Questions

100%

Coverage

Quick Navigation
1. Logging Methods
2. User Information
3. System Properties
4. User Messages
5. Date/Time
6. Utility Methods

Method Count
50+ Methods
Coverage
Logging User Info Properties Messages Date/Time