From 653b1a32ec9fe97f627730491314309e324194f0 Mon Sep 17 00:00:00 2001 From: sanjaykumar3sn Date: Fri, 24 Oct 2025 22:37:34 +0100 Subject: [PATCH 01/10] Create SLA Compliance Ratio by Assignment Group This script calculates the SLA breach percentage for each assignment group based on closed incidents in ServiceNow. It leverages GlideAggregate to count both total SLAs and breached SLAs efficiently, providing key SLA performance insights. --- .../SLA Compliance Ratio by Assignment Group | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 Core ServiceNow APIs/GlideAggregate/SLA Compliance Ratio by Assignment Group diff --git a/Core ServiceNow APIs/GlideAggregate/SLA Compliance Ratio by Assignment Group b/Core ServiceNow APIs/GlideAggregate/SLA Compliance Ratio by Assignment Group new file mode 100644 index 0000000000..96f833baca --- /dev/null +++ b/Core ServiceNow APIs/GlideAggregate/SLA Compliance Ratio by Assignment Group @@ -0,0 +1,20 @@ +Glide Aggregate Script- + +(function() { + var ga = new GlideAggregate('task_sla'); + ga.addEncodedQuery('task.sys_class_name=incident^active=false'); + ga.addAggregate('COUNT'); // All SLAs + ga.addAggregate('COUNT', 'breach', 'true'); // breached SLAs + ga.groupBy('task.assignment_group'); + ga.query(); + + gs.info('SLA Compliance Ratio by Group'); + + while (ga.next()) { + var total = parseInt(ga.getAggregate('COUNT')); + var breached = parseInt(ga.getAggregate('COUNT', 'breach', 'true')); + var rate = breached ? ((breached / total) * 100).toFixed(2) : 0; + gs.info(ga.getDisplayValue('task.assignment_group') + ': ' + rate + '% breached (' + breached + '/' + total + ')'); + } +})(); + From cff1583dc51287d10c29f72bb722835a9c40e962 Mon Sep 17 00:00:00 2001 From: sanjaykumar3sn Date: Fri, 24 Oct 2025 22:41:14 +0100 Subject: [PATCH 02/10] Update SLA Compliance Ratio by Assignment Group --- .../SLA Compliance Ratio by Assignment Group | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/Core ServiceNow APIs/GlideAggregate/SLA Compliance Ratio by Assignment Group b/Core ServiceNow APIs/GlideAggregate/SLA Compliance Ratio by Assignment Group index 96f833baca..1933f94264 100644 --- a/Core ServiceNow APIs/GlideAggregate/SLA Compliance Ratio by Assignment Group +++ b/Core ServiceNow APIs/GlideAggregate/SLA Compliance Ratio by Assignment Group @@ -18,3 +18,27 @@ Glide Aggregate Script- } })(); + +Readme: + +This script calculates the SLA breach percentage for each assignment group based on closed incidents in ServiceNow. +It leverages GlideAggregate to count both total SLAs and breached SLAs efficiently, providing key SLA performance insights. + +Useful for: + • SLA dashboards + • Support performance tracking + • Service improvement reports + +Objective + +To determine, for each assignment group: + • How many SLAs were closed + • How many of those breached + • The resulting SLA compliance percentage + +Script Logic + 1. Query the task_sla table. + 2. Filter for closed SLAs linked to incidents. + 3. Aggregate total SLAs (COUNT) and breached SLAs (COUNT, 'breach', 'true'). + 4. Group results by assignment group. + 5. Calculate breach percentage. From 9d499e303097fff4e3bbda87a48dd43d496d642e Mon Sep 17 00:00:00 2001 From: sanjaykumar3sn Date: Fri, 24 Oct 2025 22:47:11 +0100 Subject: [PATCH 03/10] Delete Core ServiceNow APIs/GlideAggregate/SLA Compliance Ratio by Assignment Group --- .../SLA Compliance Ratio by Assignment Group | 44 ------------------- 1 file changed, 44 deletions(-) delete mode 100644 Core ServiceNow APIs/GlideAggregate/SLA Compliance Ratio by Assignment Group diff --git a/Core ServiceNow APIs/GlideAggregate/SLA Compliance Ratio by Assignment Group b/Core ServiceNow APIs/GlideAggregate/SLA Compliance Ratio by Assignment Group deleted file mode 100644 index 1933f94264..0000000000 --- a/Core ServiceNow APIs/GlideAggregate/SLA Compliance Ratio by Assignment Group +++ /dev/null @@ -1,44 +0,0 @@ -Glide Aggregate Script- - -(function() { - var ga = new GlideAggregate('task_sla'); - ga.addEncodedQuery('task.sys_class_name=incident^active=false'); - ga.addAggregate('COUNT'); // All SLAs - ga.addAggregate('COUNT', 'breach', 'true'); // breached SLAs - ga.groupBy('task.assignment_group'); - ga.query(); - - gs.info('SLA Compliance Ratio by Group'); - - while (ga.next()) { - var total = parseInt(ga.getAggregate('COUNT')); - var breached = parseInt(ga.getAggregate('COUNT', 'breach', 'true')); - var rate = breached ? ((breached / total) * 100).toFixed(2) : 0; - gs.info(ga.getDisplayValue('task.assignment_group') + ': ' + rate + '% breached (' + breached + '/' + total + ')'); - } -})(); - - -Readme: - -This script calculates the SLA breach percentage for each assignment group based on closed incidents in ServiceNow. -It leverages GlideAggregate to count both total SLAs and breached SLAs efficiently, providing key SLA performance insights. - -Useful for: - • SLA dashboards - • Support performance tracking - • Service improvement reports - -Objective - -To determine, for each assignment group: - • How many SLAs were closed - • How many of those breached - • The resulting SLA compliance percentage - -Script Logic - 1. Query the task_sla table. - 2. Filter for closed SLAs linked to incidents. - 3. Aggregate total SLAs (COUNT) and breached SLAs (COUNT, 'breach', 'true'). - 4. Group results by assignment group. - 5. Calculate breach percentage. From 85317b137097ec927ca2b88c5793f97c308b7649 Mon Sep 17 00:00:00 2001 From: sanjaykumar3sn Date: Fri, 24 Oct 2025 22:48:23 +0100 Subject: [PATCH 04/10] Created script.js --- .../script.js | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 Core ServiceNow APIs/GlideAggregate/SLA Compliance Ratio by Assignment Group/script.js diff --git a/Core ServiceNow APIs/GlideAggregate/SLA Compliance Ratio by Assignment Group/script.js b/Core ServiceNow APIs/GlideAggregate/SLA Compliance Ratio by Assignment Group/script.js new file mode 100644 index 0000000000..815ab9d465 --- /dev/null +++ b/Core ServiceNow APIs/GlideAggregate/SLA Compliance Ratio by Assignment Group/script.js @@ -0,0 +1,17 @@ +(function() { + var ga = new GlideAggregate('task_sla'); + ga.addEncodedQuery('task.sys_class_name=incident^active=false'); + ga.addAggregate('COUNT'); // All SLAs + ga.addAggregate('COUNT', 'breach', 'true'); // breached SLAs + ga.groupBy('task.assignment_group'); + ga.query(); + + gs.info('SLA Compliance Ratio by Group'); + + while (ga.next()) { + var total = parseInt(ga.getAggregate('COUNT')); + var breached = parseInt(ga.getAggregate('COUNT', 'breach', 'true')); + var rate = breached ? ((breached / total) * 100).toFixed(2) : 0; + gs.info(ga.getDisplayValue('task.assignment_group') + ': ' + rate + '% breached (' + breached + '/' + total + ')'); + } +})(); From 92771219a1d2f941653768866124127faee54a4d Mon Sep 17 00:00:00 2001 From: sanjaykumar3sn Date: Fri, 24 Oct 2025 22:51:07 +0100 Subject: [PATCH 05/10] Created readme.md --- .../readme.md | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 Core ServiceNow APIs/GlideAggregate/SLA Compliance Ratio by Assignment Group/readme.md diff --git a/Core ServiceNow APIs/GlideAggregate/SLA Compliance Ratio by Assignment Group/readme.md b/Core ServiceNow APIs/GlideAggregate/SLA Compliance Ratio by Assignment Group/readme.md new file mode 100644 index 0000000000..a85f5490ec --- /dev/null +++ b/Core ServiceNow APIs/GlideAggregate/SLA Compliance Ratio by Assignment Group/readme.md @@ -0,0 +1,23 @@ +Overview + +This script calculates the SLA breach percentage for each assignment group based on closed incidents in ServiceNow. +It leverages GlideAggregate to count both total SLAs and breached SLAs efficiently, providing key SLA performance insights. + +Useful for: + • SLA dashboards + • Support performance tracking + • Service improvement reports + +Objective + +To determine, for each assignment group: + • How many SLAs were closed + • How many of those breached + • The resulting SLA compliance percentage + +Script Logic + 1. Query the task_sla table. + 2. Filter for closed SLAs linked to incidents. + 3. Aggregate total SLAs (COUNT) and breached SLAs (COUNT, 'breach', 'true'). + 4. Group results by assignment group. + 5. Calculate breach percentage. From f70e90ef6dc4286ee6e9ce7b2285300ba3330839 Mon Sep 17 00:00:00 2001 From: sanjaykumar3sn Date: Sat, 25 Oct 2025 09:48:17 +0100 Subject: [PATCH 06/10] Update script.js --- .../SLA Compliance Ratio by Assignment Group/script.js | 1 + 1 file changed, 1 insertion(+) diff --git a/Core ServiceNow APIs/GlideAggregate/SLA Compliance Ratio by Assignment Group/script.js b/Core ServiceNow APIs/GlideAggregate/SLA Compliance Ratio by Assignment Group/script.js index 815ab9d465..a31caa5a59 100644 --- a/Core ServiceNow APIs/GlideAggregate/SLA Compliance Ratio by Assignment Group/script.js +++ b/Core ServiceNow APIs/GlideAggregate/SLA Compliance Ratio by Assignment Group/script.js @@ -14,4 +14,5 @@ var rate = breached ? ((breached / total) * 100).toFixed(2) : 0; gs.info(ga.getDisplayValue('task.assignment_group') + ': ' + rate + '% breached (' + breached + '/' + total + ')'); } + })(); From e005738f88d8b8d219ea0262cab08226d8c6ef6d Mon Sep 17 00:00:00 2001 From: sanjaykumar3sn Date: Sat, 25 Oct 2025 23:10:34 +0100 Subject: [PATCH 07/10] Create licensed_user_count_by_role.js --- .../licensed_user_count_by_role.js | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 Core ServiceNow APIs/GlideAggregate/LicensedUserCount/licensed_user_count_by_role.js diff --git a/Core ServiceNow APIs/GlideAggregate/LicensedUserCount/licensed_user_count_by_role.js b/Core ServiceNow APIs/GlideAggregate/LicensedUserCount/licensed_user_count_by_role.js new file mode 100644 index 0000000000..180942c820 --- /dev/null +++ b/Core ServiceNow APIs/GlideAggregate/LicensedUserCount/licensed_user_count_by_role.js @@ -0,0 +1,23 @@ +(function() { + // Purpose: Count how many users hold each licensed role + // Roles: sys_approver, itil, business_stakeholder, admin + + var roles = ['sys_approver', 'itil', 'business_stakeholder', 'admin']; + + for (var i = 0; i < roles.length; i++) { + var roleName = roles[i]; + + var ga = new GlideAggregate('sys_user_has_role'); + ga.addQuery('role.name', roleName); + ga.addAggregate('COUNT'); + ga.query(); + + if (ga.next()) { + var count = parseInt(ga.getAggregate('COUNT'), 10); + gs.info(roleName + ': ' + count + ' licensed users'); + } else { + gs.info(roleName + ': no users found.'); + } + } + +})(); From 26020f10b93896177b1ba375628df05b0e02f8dd Mon Sep 17 00:00:00 2001 From: sanjaykumar3sn Date: Sat, 25 Oct 2025 23:12:26 +0100 Subject: [PATCH 08/10] Create readme.md --- .../GlideAggregate/LicensedUserCount/readme.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 Core ServiceNow APIs/GlideAggregate/LicensedUserCount/readme.md diff --git a/Core ServiceNow APIs/GlideAggregate/LicensedUserCount/readme.md b/Core ServiceNow APIs/GlideAggregate/LicensedUserCount/readme.md new file mode 100644 index 0000000000..d5617f2bc2 --- /dev/null +++ b/Core ServiceNow APIs/GlideAggregate/LicensedUserCount/readme.md @@ -0,0 +1,14 @@ +# Licensed User Count by Role Using GlideAggregate + +# Overview +This script counts how many **licensed users** hold specific ServiceNow roles using the `GlideAggregate` API. +It’s useful for **license compliance**, **role audits**, and **access management reporting**. + +The licensed roles analyzed: +- sys_approver +- itil +- business_stakeholder +- admin + +# Objective +To provide a simple, fast, and accurate way to count licensed users per role directly at the database level using `GlideAggregate`. From 2ca888c879ea6eac4fc89433aa6e7eaecbb26da2 Mon Sep 17 00:00:00 2001 From: sanjaykumar3sn Date: Sat, 25 Oct 2025 23:29:00 +0100 Subject: [PATCH 09/10] Create Weekly_LicensedUser_Access_Revoke_90Days.js --- ...eekly_LicensedUser_Access_Revoke_90Days.js | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 Server-Side Components/Scheduled Jobs/Licensed User Access Job/Weekly_LicensedUser_Access_Revoke_90Days.js diff --git a/Server-Side Components/Scheduled Jobs/Licensed User Access Job/Weekly_LicensedUser_Access_Revoke_90Days.js b/Server-Side Components/Scheduled Jobs/Licensed User Access Job/Weekly_LicensedUser_Access_Revoke_90Days.js new file mode 100644 index 0000000000..a8c5efa4ad --- /dev/null +++ b/Server-Side Components/Scheduled Jobs/Licensed User Access Job/Weekly_LicensedUser_Access_Revoke_90Days.js @@ -0,0 +1,44 @@ +(function executeWeeklyJob() { + + var DAYS_INACTIVE_THRESHOLD = 90; // number of days + var licensedRoles = ['itil', 'sys_approver', 'admin', 'business_stakeholder']; + + var roleGroupMap = { + 'itil': 'ITIL Group', + 'sys_approver': 'Approver Group', + 'admin': 'Admin Group', + 'business_stakeholder': 'Business Stakeholder Group' + }; + + var thresholdDate = new GlideDateTime(); + thresholdDate.addDaysUTC(-DAYS_INACTIVE_THRESHOLD); + + for (var i = 0; i < licensedRoles.length; i++) { + var role = licensedRoles[i]; + var groupName = roleGroupMap[role]; + + var userRoleGR = new GlideRecord('sys_user_has_role'); + userRoleGR.addQuery('role.name', role); + userRoleGR.addQuery('user.active', true); + userRoleGR.query(); + + while (userRoleGR.next()) { + var user = userRoleGR.user.getRefRecord(); + var lastLogin = user.last_login_time; + + // user never logged in or inactive beyond threshold + if (!lastLogin || lastLogin < thresholdDate) { + gs.info('Revoking access for user: ' + user.name + ' (' + role + ')'); + + // Remove from group + var groupGR = new GlideRecord('sys_user_grmember'); + groupGR.addQuery('user', user.sys_id); + groupGR.addQuery('group.name', groupName); + groupGR.query(); + while (groupGR.next()) { + groupGR.deleteRecord(); + } + } + } + } +})(); From 82446a53c8c0ef3f90e8fe292289677f3157a01f Mon Sep 17 00:00:00 2001 From: sanjaykumar3sn Date: Sat, 25 Oct 2025 23:33:01 +0100 Subject: [PATCH 10/10] Create readme.md --- .../Licensed User Access Job/readme.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 Server-Side Components/Scheduled Jobs/Licensed User Access Job/readme.md diff --git a/Server-Side Components/Scheduled Jobs/Licensed User Access Job/readme.md b/Server-Side Components/Scheduled Jobs/Licensed User Access Job/readme.md new file mode 100644 index 0000000000..86cb3adb74 --- /dev/null +++ b/Server-Side Components/Scheduled Jobs/Licensed User Access Job/readme.md @@ -0,0 +1,16 @@ +Weekly Licensed User Access Review (90 Day Inactivity) + +# Overview +This scheduled job runs weekly and automatically revokes access for licensed users who have been inactive/not logged in for more than 90 days. +It ensures license compliance, cost control, and adherence to security policies. + +# Objective +To identify active users holding licensed roles who have not logged into ServiceNow within the past 90 days and revoke their access by removing them from their respective groups. + +# Configuration Summary + +1. Threshold - 90 days since last login +2. Frequency - Weekly +3. Licensed Roles Checked - `itil`, `sys_approver`, `admin`, `business_stakeholder` +4. Groups Managed - ITIL Group, Approver Group, Admin Group, Business Stakeholder Group +5. Execution Context - Scheduled Script Execution