diff --git a/Server-Side Components/Scheduled Jobs/Role Usage Analyzer/README.md b/Server-Side Components/Scheduled Jobs/Role Usage Analyzer/README.md new file mode 100644 index 0000000000..910c809b28 --- /dev/null +++ b/Server-Side Components/Scheduled Jobs/Role Usage Analyzer/README.md @@ -0,0 +1,26 @@ +# Role Usage Analyzer for ServiceNow + +## Overview + +This script analyzes role assignments in your ServiceNow instance and identifies roles that are assigned to users but appear to be unused. It cross-references user activity logs to determine whether assigned roles are actively used. + +## Features + +- Scans all roles assigned to users +- Checks user activity via `sys_history_line` to infer role usage +- Flags roles that are assigned but show no signs of usage +- Logs unused roles and the number of users assigned to them + +## Usage + +1. Navigate to **System Definition > Scheduled Jobs**. +2. Create a new Script Include or Scheduled Job named `Role_Usage_Analyzer`. +3. Paste the contents of `Role_Usage_Analyzer.js` into the script field. +4. Run the script manually or schedule it to run periodically (e.g., weekly or monthly). + +## Notes + +- This script uses `sys_history_line` to infer user activity. For more accurate results, consider integrating with login logs or audit tables if available. +- You can extend the script to automatically notify administrators or generate reports. +- Roles used only in background scripts or integrations may not show up in history logs — manual review is recommended. + diff --git a/Server-Side Components/Scheduled Jobs/Role Usage Analyzer/code.js b/Server-Side Components/Scheduled Jobs/Role Usage Analyzer/code.js new file mode 100644 index 0000000000..dfb429afeb --- /dev/null +++ b/Server-Side Components/Scheduled Jobs/Role Usage Analyzer/code.js @@ -0,0 +1,43 @@ + + // Role Usage Analyzer Script + // Description: Identifies roles assigned to users that may be unused. + + var roleUsageMap = {}; + var grUserRole = new GlideRecord('sys_user_has_role'); + grUserRole.query(); + + while (grUserRole.next()) { + var userId = grUserRole.user.toString(); + var roleId = grUserRole.role.toString(); + + if (!roleUsageMap[roleId]) { + roleUsageMap[roleId] = { + users: [], + used: false + }; + } + + roleUsageMap[roleId].users.push(userId); + } + + var grHistory = new GlideRecord('sys_history_line'); + grHistory.addQuery('user', 'ISNOTEMPTY'); + grHistory.query(); + + while (grHistory.next()) { + var userId = grHistory.user.toString(); + for (var roleId in roleUsageMap) { + if (roleUsageMap[roleId].users.indexOf(userId) !== -1) { + roleUsageMap[roleId].used = true; + } + } + } + + for (var roleId in roleUsageMap) { + if (!roleUsageMap[roleId].used) { + var grRole = new GlideRecord('sys_user_role'); + if (grRole.get(roleId)) { + gs.info('[Role Usage Analyzer] Unused Role: ' + grRole.name + ' | Assigned to Users: ' + roleUsageMap[roleId].users.length); + } + } + }