The CreatorCon Call for Content is officially open! Get started here.

Deactivate user when not found on the LDAP import

Mark_Bailey
Mega Guru

Greetings

Our LDAP management seems to be a lot different than most companies. The out of box deactivation script is looking for the users to go into a specific OU of have a specific field marked.   I need a much simpler script. IF a user is not found on the AD import and already exist as active on ServiceNow AND was initially imported via LDAP (User Source is not blank) , then deactivate.

I am hoping someone might have something very similar I can do some minor adjusting to.

Out of Box on before deactivated scriptnot being used (Part of the LDAP import)

var ctrl = parseInt(source.u_useraccountcontrol, 10);

ctrl = ctrl.toString(16);

//The relevant digit is the final one

//A final hex digit value of '2' in 'ctrl' means disabled

if (ctrl.substr(-1) == "2") {

    target.active = false;

    target.locked_out = true;

    if (action == 'insert')

          ignore = true;

} else {

    //Optional: Reactivate and unlock the user account

    //target.active = true;

    //target.locked_out = ctrl.substr(-2, 1) == "1";

}

28 REPLIES 28

Have you made any tweaks since posting? running into the same issue.


I did not do anything at this point.



Thank you,



Mark Bailey


on: Description: Description: Contact


ServiceNow Administrator


281.776.6655


Michael Domke
Tera Guru

This post was certainly helpful for me. I needed a way to disable active ServiceNow user accounts that did not have a corresponding account in Active Directory. We have Orchestration and I know I could have built something using that but I was certain there should be a way to leverage what LDAP had already started. And the post by justin.drysdale was just what I needed - utilize the import set LDAP created. Here's what I came up with and it's worked great for me so far.



We have a Scheduled Data Import for each of our LDAP data sources. There's an Execute Post-Import Script property that when checked, allows you to write script after the Scheduled Data Import completes. In the script, you have access to the import_set.number value which represents the import set that just completed.



So, using what Justin started, the validation of users can be automated when the Scheduled Data Import completes. Here's the script I'm using in the Post Script of the Scheduled Data Import:



var importset_arr = [], sysuser_arr = [], inactive_arr = [], arrUtil = new ArrayUtil();



var importSet = import_set.number;



// Fill the importset_arr array with all User Sys_IDs from the Import Set that just completed.


var importSetRow = new GlideRecord('sys_import_set_row');


importSetRow.addQuery('sys_import_set.number', importSet);


importSetRow.query();


while (importSetRow.next()) {


  importset_arr.push(importSetRow.sys_target_sys_id.toString());


}



// Fill the sysuser_arr array with the sys_ids of all Active Employees and Contractors that are currently


// in the User (sys_user) table.


var user = new GlideRecord('sys_user');


user.addEncodedQuery('active=true^u_person_type=E^ORu_person_type=C');


user.query();


while (user.next()) {


  sysuser_arr.push(user.sys_id.toString());


}



// Compare the sysuser_arr with the importset_arr and return an array of users (sys_ids) that exist in


// the sysuser_arr but are not in the importset_arr. This result represents active employees and


// contractors who are in ServiceNow but do not have an Active Directory account.


inactive_arr = arrUtil.diff(sysuser_arr, importset_arr);



// For each user in the inactive_arr array, inactivate their ServiceNow users account (active=false)


for (var i = 0; i < inactive_arr.length; i++) {


  user = new GlideRecord('sys_user');


  if (user.get(inactive_arr[i])) {


      user.active = false;


      user.u_comments = 'Deactivated during LDAP update ' + importSet + '. User not found in AD.';


      user.update();


  }


}



gs.log('LDAP User Import complete. ImportSet Number: ' + importSet + '\nAD User count: ' + importset_arr.length + '\nSys_User Count: ' + sysuser_arr.length + '\nInactive Count: ' + inactive_arr.length);



Word of caution: Be sure to tweak this script so the list of users from the import set (users from AD) and the users from the sys_user table represent the entire population you want to compare. I know my LDAP data source returns the entire list of employees and contractors I want to compare to the sys_user table. And I've queried the sys_user table to return a result set of only active employees and contractors. We have loads more users in the sys_user table that are used for Visitors, Test Accounts, Non-Person Accounts, etc, that I know are not in AD but also do not want to deactivate in ServiceNow.



Hope this helps,


Michael


That's awesome. I can't wait to try this out. Thank you so much for sharing this.




Thank you,



Mark Bailey


on: Description: Description: Contact


ServiceNow Administrator


281.776.6655


Did you try it out? I'm looking at implement the script but when I look at the results of the following:



// For each user in the inactive_arr array, inactivate their ServiceNow users account (active=false)  


for (var i = 0; i < inactive_arr.length; i++) {  


  user = new GlideRecord('sys_user');  


  if (user.get(inactive_arr[i])) {  


      //user.active = false;  


      //user.u_comments = 'Deactivated during LDAP update ' + importSet + '. User not found in AD.';  


      //user.update();


      gs.log('Disabled user: ' + user.getDisplayValue() + ", " + user.location.getDisplayValue() + ". User not found in AD.");


  }  


}



The system tries to disable ALL users and not just the inactive ones even though the inactive array is smaller:



importset_arr count: 10604


sysuser_arr count: 11995