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.'); + } + } + +})(); 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`. 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(); + } + } + } + } +})(); 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