HR Leave · Australia

ServiceNow Administration Complete Guide — دليل الإدارة الشامل

ServiceNow Australia · Custom app · Arabic + English readable · scripts copy/paste ready

App typeCustom
Scopex_786686_hr_leave
sys_idc84db0e8839f0b509f02b0d6feaad3c9
Replace{BASE} = your instance
Instance URLs Users Roles ACL Update Sets

ServiceNow Administration Complete Guide — دليل الإدارة الشامل

Platform: ServiceNow Australia (Sep 2026)
دليل شامل لإدارة النظام والمستخدمين والأمان


Table of Contents

  1. User Administration
  2. Group Management
  3. Role Management
  4. Security and ACLs
  5. System Properties
  6. Email and Notifications
  7. Scheduled Jobs
  8. Import and Transform
  9. Instance Management
  10. Audit and Compliance

1. User Administration

Direct URL: {BASE}/sys_user_list.do

Create User

var gr = new GlideRecord('sys_user');
gr.initialize();
gr.user_name = 'ahmed.hassan';
gr.first_name = 'Ahmed';
gr.last_name = 'Hassan';
gr.email = 'ahmed@company.com';
gr.active = true;
gr.insert();

Bulk User Import

var users = [
    { user_name: 'user1', first_name: 'User', last_name: 'One', email: 'user1@co.com' },
    { user_name: 'user2', first_name: 'User', last_name: 'Two', email: 'user2@co.com' }
];

for (var i = 0; i < users.length; i++) {
    var data = users[i];
    var gr = new GlideRecord('sys_user');
    if (!gr.get('user_name', data.user_name)) {
        gr.initialize();
        gr.user_name = data.user_name;
        gr.first_name = data.first_name;
        gr.last_name = data.last_name;
        gr.email = data.email;
        gr.active = true;
        gr.insert();
        gs.info('Created: ' + data.user_name);
    }
}

2. Group Management

Direct URL: {BASE}/sys_user_group_list.do

Create Groups

var groups = [
    { name: 'HR Leave Approvers', roles: ['x_786686_hr_leave.manager'] },
    { name: 'HR Leave Admins', roles: ['x_786686_hr_leave.hr_admin'] }
];

for (var i = 0; i < groups.length; i++) {
    var data = groups[i];
    var gr = new GlideRecord('sys_user_group');
    if (!gr.get('name', data.name)) {
        gr.initialize();
        gr.name = data.name;
        gr.active = true;
        var groupId = gr.insert();

        // Add roles
        for (var j = 0; j < data.roles.length; j++) {
            var role = new GlideRecord('sys_user_role');
            if (role.get('name', data.roles[j])) {
                var grRole = new GlideRecord('sys_group_has_role');
                grRole.initialize();
                grRole.group = groupId;
                grRole.role = role.sys_id;
                grRole.insert();
            }
        }
    }
}

Add User to Group

function addUserToGroup(username, groupName) {
    var user = new GlideRecord('sys_user');
    var group = new GlideRecord('sys_user_group');

    if (!user.get('user_name', username) || !group.get('name', groupName)) {
        return false;
    }

    var member = new GlideRecord('sys_user_grmember');
    member.addQuery('user', user.sys_id);
    member.addQuery('group', group.sys_id);
    member.query();

    if (!member.hasNext()) {
        member.initialize();
        member.user = user.sys_id;
        member.group = group.sys_id;
        member.insert();
        return true;
    }
    return false;
}

3. Role Management

Direct URL: {BASE}/sys_user_role_list.do

Create Application Roles

var roles = [
    { name: 'x_786686_hr_leave.employee', desc: 'Base employee role' },
    { name: 'x_786686_hr_leave.manager', desc: 'Manager approval role', contains: ['x_786686_hr_leave.employee'] },
    { name: 'x_786686_hr_leave.hr_admin', desc: 'Full admin', contains: ['x_786686_hr_leave.manager'] }
];

for (var i = 0; i < roles.length; i++) {
    var data = roles[i];
    var role = new GlideRecord('sys_user_role');
    if (!role.get('name', data.name)) {
        role.initialize();
        role.name = data.name;
        role.description = data.desc;
        var roleId = role.insert();

        if (data.contains) {
            for (var j = 0; j < data.contains.length; j++) {
                var child = new GlideRecord('sys_user_role');
                if (child.get('name', data.contains[j])) {
                    var contain = new GlideRecord('sys_user_role_contains');
                    contain.initialize();
                    contain.role = roleId;
                    contain.contains = child.sys_id;
                    contain.insert();
                }
            }
        }
    }
}

Role Audit

function auditRoles(rolePrefix) {
    var report = [];

    var roles = new GlideRecord('sys_user_role');
    roles.addQuery('name', 'STARTSWITH', rolePrefix);
    roles.query();

    while (roles.next()) {
        var info = {
            name: roles.name.toString(),
            direct_users: 0,
            groups: []
        };

        // Count direct assignments
        var ur = new GlideAggregate('sys_user_has_role');
        ur.addQuery('role', roles.sys_id);
        ur.addAggregate('COUNT');
        ur.query();
        if (ur.next()) info.direct_users = parseInt(ur.getAggregate('COUNT'));

        // Get groups
        var gr = new GlideRecord('sys_group_has_role');
        gr.addQuery('role', roles.sys_id);
        gr.query();
        while (gr.next()) {
            info.groups.push(gr.group.getDisplayValue());
        }

        report.push(info);
    }
    return report;
}

gs.info(JSON.stringify(auditRoles('x_786686_hr_leave'), null, 2));

4. Security and ACLs

Direct URL: {BASE}/sys_security_acl_list.do

ACL Examples

// Read own records only
// Table: x_786686_hr_leave_request
// Operation: read
// Role: x_786686_hr_leave.employee

(function executeACL() {
    if (gs.hasRole('x_786686_hr_leave.hr_admin')) return true;

    if (gs.hasRole('x_786686_hr_leave.manager')) {
        return current.employee.manager == gs.getUserID() ||
               current.employee == gs.getUserID();
    }

    return current.employee == gs.getUserID();
})()

// Write only draft records
// Operation: write
(function executeACL() {
    if (gs.hasRole('x_786686_hr_leave.hr_admin')) return true;

    return current.employee == gs.getUserID() && current.state == 1;
})()

Data Policy

Table: x_786686_hr_leave_request
Condition: state != 1  # Not draft
Apply to: All

Actions:
  - leave_type: Read only
  - start_date: Read only
  - end_date: Read only
  - employee: Read only

5. System Properties

Direct URL: {BASE}/sys_properties_list.do

Create Properties

var props = [
    { name: 'x_786686_hr_leave.max_days', value: '30', type: 'integer' },
    { name: 'x_786686_hr_leave.carryover', value: '5', type: 'integer' },
    { name: 'x_786686_hr_leave.notifications', value: 'true', type: 'true_false' },
    { name: 'x_786686_hr_leave.hr_email', value: 'hr@company.com', type: 'string' }
];

for (var i = 0; i < props.length; i++) {
    var p = props[i];
    var gr = new GlideRecord('sys_properties');
    if (!gr.get('name', p.name)) {
        gr.initialize();
        gr.name = p.name;
        gr.value = p.value;
        gr.type = p.type;
        gr.insert();
    }
}

Use Properties

var maxDays = parseInt(gs.getProperty('x_786686_hr_leave.max_days', '30'));
var enabled = gs.getProperty('x_786686_hr_leave.notifications') == 'true';

6. Email and Notifications

Direct URL: {BASE}/sysevent_email_action_list.do

Create Notification

Name: HR Leave - Request Submitted
Table: x_786686_hr_leave_request
When: Record inserted or updated
Condition: State changes to 2

Recipients: manager field

Subject: Leave Request ${number} - ${employee.name}

Body:
Dear ${manager.first_name},

A leave request needs your approval:

Employee: ${employee.name}
Type: ${leave_type}
Dates: ${start_date} to ${end_date}
Duration: ${duration_days} days

Click here to review: ${URI_REF}

HR System

Register Events

var events = [
    'x_786686_hr_leave.submitted',
    'x_786686_hr_leave.approved',
    'x_786686_hr_leave.rejected'
];

for (var i = 0; i < events.length; i++) {
    var gr = new GlideRecord('sysevent_register');
    if (!gr.get('event_name', events[i])) {
        gr.initialize();
        gr.event_name = events[i];
        gr.table = 'x_786686_hr_leave_request';
        gr.insert();
    }
}

// Queue event
gs.eventQueue('x_786686_hr_leave.submitted', current,
    current.employee.email, current.manager.email);

7. Scheduled Jobs

Direct URL: {BASE}/sysauto_script_list.do

Daily Balance Check

// Run: Daily at 06:00

(function() {
    var threshold = 3;
    var year = new GlideDateTime().getYearLocalTime();

    var alloc = new GlideRecord('x_786686_hr_leave_allocation');
    alloc.addQuery('year', year);
    alloc.query();

    while (alloc.next()) {
        var remaining = (parseInt(alloc.days_allocated) || 0) - 
                       (parseInt(alloc.days_used) || 0);

        if (remaining > 0 && remaining <= threshold) {
            gs.eventQueue('x_786686_hr_leave.balance.low', alloc,
                alloc.employee.email.toString(), remaining.toString());
        }
    }
})();

Approval Reminder

// Run: Daily at 09:00

(function() {
    var twoDaysAgo = new GlideDateTime();
    twoDaysAgo.addDays(-2);

    var gr = new GlideRecord('x_786686_hr_leave_request');
    gr.addQuery('state', 2);  // Awaiting approval
    gr.addQuery('sys_updated_on', '<', twoDaysAgo);
    gr.query();

    while (gr.next()) {
        gs.eventQueue('x_786686_hr_leave.reminder', gr,
            gr.manager.email.toString(), gr.number.toString());
        gr.work_notes = 'Reminder sent to manager';
        gr.update();
    }
})();

8. Import and Transform

Direct URL: {BASE}/sys_import_set_table_list.do

Transform Map Script

// onBefore
(function runTransformScript(source, map, log, target) {

    if (!source.u_employee_id || !source.u_start_date) {
        ignore = true;
        return;
    }

    var emp = new GlideRecord('sys_user');
    emp.addQuery('employee_number', source.u_employee_id);
    emp.query();

    if (emp.next()) {
        source.u_employee_sys_id = emp.sys_id.toString();
    } else {
        log.error('Employee not found: ' + source.u_employee_id);
        ignore = true;
    }

})(source, map, log, target);

// Field Map: employee
answer = source.u_employee_sys_id;

// Field Map: leave_type
answer = (function() {
    var map = { 'AL': 'annual', 'SL': 'sick', 'EL': 'emergency' };
    return map[source.u_leave_type] || 'annual';
})();

9. Instance Management

Health Check Script

function instanceHealthCheck() {
    var report = {
        timestamp: new GlideDateTime().getDisplayValue(),
        stats: {},
        warnings: []
    };

    // Active users
    var users = new GlideAggregate('sys_user');
    users.addQuery('active', true);
    users.addAggregate('COUNT');
    users.query();
    if (users.next()) {
        report.stats.active_users = parseInt(users.getAggregate('COUNT'));
    }

    // Open incidents
    var inc = new GlideAggregate('incident');
    inc.addQuery('state', 'NOT IN', '6,7');
    inc.addAggregate('COUNT');
    inc.query();
    if (inc.next()) {
        report.stats.open_incidents = parseInt(inc.getAggregate('COUNT'));
    }

    // Pending leave requests
    var leave = new GlideAggregate('x_786686_hr_leave_request');
    leave.addQuery('state', 2);
    leave.addAggregate('COUNT');
    leave.query();
    if (leave.next()) {
        var pending = parseInt(leave.getAggregate('COUNT'));
        report.stats.pending_leave = pending;
        if (pending > 50) {
            report.warnings.push('High pending leave requests: ' + pending);
        }
    }

    return report;
}

gs.info(JSON.stringify(instanceHealthCheck(), null, 2));

10. Audit and Compliance

Direct URL: {BASE}/sys_audit_list.do

Audit Log Query

function getAuditTrail(table, recordId, days) {
    var trail = [];
    var since = new GlideDateTime();
    since.addDays(-days);

    var audit = new GlideRecord('sys_audit');
    audit.addQuery('tablename', table);
    audit.addQuery('documentkey', recordId);
    audit.addQuery('sys_created_on', '>=', since);
    audit.orderByDesc('sys_created_on');
    audit.query();

    while (audit.next()) {
        trail.push({
            field: audit.fieldname.toString(),
            old_value: audit.oldvalue.toString(),
            new_value: audit.newvalue.toString(),
            user: audit.user.getDisplayValue(),
            time: audit.sys_created_on.getDisplayValue()
        });
    }
    return trail;
}

Direct URLs Reference

Page URL
Users {BASE}/sys_user_list.do
Groups {BASE}/sys_user_group_list.do
Roles {BASE}/sys_user_role_list.do
ACLs {BASE}/sys_security_acl_list.do
Properties {BASE}/sys_properties_list.do
Notifications {BASE}/sysevent_email_action_list.do
Scheduled Jobs {BASE}/sysauto_script_list.do
Import Sets {BASE}/sys_import_set_table_list.do
Audit {BASE}/sys_audit_list.do
Plugins {BASE}/v_plugin_list.do

Next: Development Guide | Portals Guide