Background Scripts
Report Active Users Without Departments
Identify active user accounts with an empty department reference for manual data-quality review, without changing user records.
(function reportMissingUserDepartments() {
var prefix = '[SN-Tricks:MissingUserDepartments]';
var limit = 100;
try {
var users = new GlideRecord('sys_user');
users.addQuery('active', true);
users.addNullQuery('department');
users.orderBy('sys_id');
users.setLimit(limit + 1);
users.query();
var shown = 0;
var truncated = false;
while (users.next()) {
if (shown >= limit) {
truncated = true;
break;
}
gs.info(prefix + ' user=' + users.getUniqueValue());
shown++;
}
gs.info(prefix + ' Reported ' + shown + ' active user(s) without departments.' +
(truncated ? ' More matches exist; output capped at ' + limit + '.' : ' All matching users shown.'));
} catch (error) {
gs.error(prefix + ' Report failed; disregard partial output: ' + error);
}
})();How to use it
1. As an authorized administrator, open System Definition > Scripts - Background in a non-production instance and select Global scope. This custom diagnostic reads the OOB sys_user table. No cross-scope access is required in Global. Keep limit a positive whole number. 2. Run the script and search output or system logs for [SN-Tricks:MissingUserDepartments]. It selects active users with an empty department reference. Populated references, including inactive departments and dangling references, are outside this report. 3. In sub-production, test active users with empty and populated departments, plus inactive users with empty departments. Only active users with empty departments should appear. Compare with the user list using the same filters and domain context. Use dedicated test records. 4. Test zero, exactly 100, and 101 matches. Results are ordered by sys_id and capped at 100. One extra fetched row detects truncation; a capped count is not a total. Only user IDs are logged, not names or contact details. Restrict log access appropriately. 5. Review results with the identity-data owner before changing records. Department can intentionally be empty for integration accounts, external users, and other account types. The report does not determine employment status or select a department automatically. 6. Administrative GlideRecord is not an ACL-filtered end-user report. Domain separation, query business rules, and concurrent changes can affect results. The output cap does not bound database scan cost; evaluate runtime on representative data before production use. 7. If an error is logged, disregard partial output. This script performs no inserts, updates, deletes, or notifications; no data rollback is needed. Ad hoc execution creates no reusable update-set configuration. Local mock checks do not replace validation on a ServiceNow instance.
Adapt the table names, fields, and conditions to your instance. Test the behavior in a development environment before using it in production.