Skip to content

Commit 0e2dc1e

Browse files
Scheduled job ServiceNow code snippet
Auto deactivate inactive users
1 parent 80b7f89 commit 0e2dc1e

File tree

1 file changed

+95
-0
lines changed

1 file changed

+95
-0
lines changed
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
(function executeAutoUserCleanup() {
2+
3+
/***************************************************************
4+
* AUTO CLEANUP INACTIVE USERS - MONTHLY JOB
5+
* ------------------------------------------------------------
6+
* This script automatically deactivates users who have not
7+
* logged in for a defined number of months. It can also send
8+
* notifications to both the user and their manager.
9+
*
10+
* SAFETY: Use DRY_RUN = true first to test (no updates).
11+
***************************************************************/
12+
13+
// === CONFIGURATION ===
14+
var MONTHS_THRESHOLD = 3; // Inactive period threshold (in months)
15+
var DRY_RUN = true; // true = test mode, no database updates
16+
var BATCH_LIMIT = 1000; // Max records per execution
17+
var FROM_EMAIL = 'no-reply@yourcompany.com'; // sender email address
18+
19+
// === STEP 1: Calculate cutoff date ===
20+
var cutoffDate = new GlideDateTime();
21+
cutoffDate.addMonths(-MONTHS_THRESHOLD);
22+
23+
gs.info('[UserCleanup] Job started. Cutoff date: ' + cutoffDate.getDisplayValue() +
24+
' | DRY_RUN: ' + DRY_RUN + ' | Threshold: ' + MONTHS_THRESHOLD + ' months');
25+
26+
// === STEP 2: Query eligible users ===
27+
var userGr = new GlideRecord('sys_user');
28+
userGr.addQuery('active', true); // only active users
29+
userGr.addQuery('sys_created_on', '<=', cutoffDate); // created before cutoff
30+
userGr.addQuery('last_login_time', '<=', cutoffDate); // no recent login
31+
userGr.setLimit(BATCH_LIMIT); // safety limit
32+
userGr.query();
33+
34+
var totalFound = 0;
35+
var totalDeactivated = 0;
36+
37+
// === STEP 3: Loop through each user ===
38+
while (userGr.next()) {
39+
totalFound++;
40+
41+
var userName = userGr.name.toString();
42+
var userEmail = userGr.email.toString();
43+
var lastLogin = userGr.last_login_time ? userGr.last_login_time.getDisplayValue() : 'Never';
44+
var managerEmail = (userGr.manager && userGr.manager.email) ? userGr.manager.email.toString() : null;
45+
46+
gs.info('[UserCleanup] Found user: ' + userName +
47+
' | Email: ' + userEmail +
48+
' | Last Login: ' + lastLogin +
49+
' | Manager: ' + (managerEmail || 'None'));
50+
51+
if (!DRY_RUN) {
52+
53+
// === STEP 4: Deactivate the user ===
54+
userGr.active = false;
55+
userGr.update();
56+
totalDeactivated++;
57+
58+
// === STEP 5: Send notification to user ===
59+
if (userEmail) {
60+
var subjectUser = 'Your ServiceNow account has been deactivated due to inactivity';
61+
var bodyUser =
62+
'Hello ' + userName + ',\n\n' +
63+
'Your ServiceNow account has been automatically deactivated because there has been no login activity ' +
64+
'for over ' + MONTHS_THRESHOLD + ' months.\n\n' +
65+
'If you believe this is a mistake or require access, please contact the IT Service Desk.\n\n' +
66+
'Regards,\nIT Service Management Team';
67+
68+
gs.email(FROM_EMAIL, userEmail, subjectUser, bodyUser);
69+
gs.info('[UserCleanup] Email sent to user: ' + userEmail);
70+
}
71+
72+
// === STEP 6: Send notification to manager ===
73+
if (managerEmail) {
74+
var subjectMgr = 'User under your management has been deactivated';
75+
var bodyMgr =
76+
'Hello,\n\n' +
77+
'The following user under your management has been deactivated due to inactivity:\n\n' +
78+
'User: ' + userName + '\n' +
79+
'Last Login: ' + lastLogin + '\n\n' +
80+
'If this account is still required, please raise a ServiceNow access request.\n\n' +
81+
'Regards,\nIT Service Management Team';
82+
83+
gs.email(FROM_EMAIL, managerEmail, subjectMgr, bodyMgr);
84+
gs.info('[UserCleanup] Email sent to manager: ' + managerEmail);
85+
}
86+
}
87+
}
88+
89+
// === STEP 7: Log summary ===
90+
gs.info('[UserCleanup] Total users found: ' + totalFound);
91+
gs.info('[UserCleanup] Total users deactivated: ' + totalDeactivated +
92+
(DRY_RUN ? ' (Dry Run - no records updated)' : ''));
93+
94+
})();
95+

0 commit comments

Comments
 (0)