How to update active to false on LDAP user import without otherwise updating the user account
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎05-04-2023 01:04 PM
My organization uses LDAP to import users from Azure AD. The issue that my team is having is that our import process brings in inactive users and their information with this import. Specifically this is an issue with location-related fields where users that left the company some time ago (with non-standard location assigned to them in AD) will keep getting brought in and Locations will get re-imported.
Using an OU Definition filter to ignore inactive users completely does not work because then users who leave the company will not get deactivated in the first place. I also tried to use variations of transform scripts (onBefore, OnStart) to try to set inactive users UserAccountControl value on their ServiceNow user profile, but with scripts I can only seem to manage to either update all the fields on the inactive user records or ignore the inactive user completely.
How can I update just one field on an inactive user’s account without doing a transform/import on all the other fields in a user’s account?
For more info, I am not able to remove Location or other user fields from the LDAP import process because Location is an important field for setting up IT support in our organization. I know that I could filter out inactive users and then run a schedule job on users that have not been refreshed from LDAP for a certain period of time to find inactive users… but my organization’s ServiceNow product owner does not like the idea of having any additional window of time where people who have left the company retain their ServiceNow access.
Information on our environment and attempts made below:
Our current LDAP OU Definition filter is (&(objectClass=person)(sn=*)(EmployeeID=*)(!(objectClass=computer))) and using this filter with (!(userAccountControl=512)) or to filter out specific OUs means that users are not made inactive when they leave the company. I don’t think a filter is going to work for what I need but I am open to suggestions.
The script below is one I’ve seen in a number of places, and people have suggested that this will do what I am hoping to accomplish but the reality is that all fields on inactive user accounts are still being updated. I have tried versions of this script as part of the table transform map script itself, and also as an onBefore and onStart transform script. I have only managed to either completely ignore the inactive account or update all of the fields on the account. I only want to update the userAccountControl field we have on the inactive user records and no other fields after they have been deactivated.
//This script results in inactive users records being updated in their entirety
//Deactivate LDAP-disabled users during transform based on 'userAccountControl' attribute value 514
if (source.u_useraccountcontrol == '514') {
target.active = false;
target.locked_out = true;
//Ignore any insert of a disabled record
if (action == 'insert') {
ignore = true;
}
}
I also tried the below script in a few places.
//This script has the same problem as a filter, and users who leave the company are not set to inactive
if (source.u_useraccountcontrol == '514' || action == 'insert') {
target.u_ad_user_account = '514';
//update; //when this is included it updates all the import fields for inactive users
ignore = true;
}

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎05-04-2023 01:22 PM
I found the easiest way to deal with this kind of thing is to do the following.
1 - Filter out disabled users in your AD query. You can use (!(useraccountcontrol:1.2.840.113556.1.4.803:=2)).
2 - Add a field to the user table called "Last AD Update" and make it a date time field.
3 - Add the "Last AD Update" field to your transform map and set the value to the current date time.
4 - Create an onComplete script that uses the below code. The script will disable those accounts that are syncing with AD but did not sync with the last query from AD.
5 - Schedule the import of AD information to occur once per day in the wee hours of the morning.
//onClomplete script, this will update any users who has a value in the "Last AD Update" field and that
//value is before today and the account is active will have the active field set to false.
//So accounts that are not being synced with AD will not be inactivated.
var users = new GlideRecord("sys_user");
users.addEncodedQuery("u_last_ad_update<javascript:gs.beginningOfToday()^u_last_ad_updateISNOTEMPTY^active=true");
users.setValue("active", false);
users.updateMultiple();
This only works if you are importing from AD once a day. If you would like to do it more often you can but things are a bit more complicated and no matter what your query has to pull over all of the active users.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎05-04-2023 01:44 PM
Thank you for the response, Drew!
Unfortunately our AD import is 3 times a day so I'll have to make some adjustments but I'll give it a try and see if this could work for us.

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎05-04-2023 02:00 PM
Its all about designing the query so it does not get the records you just imported. So you could do "Last AD Update" < 3 hours ago and then import every 4 hours. You just need to make sure you get all the users each time.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎05-08-2023 11:17 AM
I appreciate your advice on this solution, which does appear to work as you describe. However, my manager has decided to veto solutions using an update/refresh from AD field on the user records because it won't be clear when the last actual update of user account information occurred. So unfortunately this solution is not going to work for me after all.
Thanks very much, though. If I don't get any responses in the near future I will mark your answer as the solution.