function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Jeff Bryant 16Jeff Bryant 16 

Scheduled batch job to deactivate users older than 60 days

I'm trying to create a scheduled batch job that deactivates users that are older than 60 days but it seems to not be working. I believe that it's the query portion that is the culprit. 


global class DeactivateUsers implements Database.Batchable<sObject> {
     global Database.QueryLocator start(Database.BatchableContext bc) {
          return Database.getQueryLocator('SELECT Id, LastLoginDate FROM User WHERE IsActive = TRUE AND LastLoginDate > LAST_N_DAYS:60');
     }
     global void execute(Database.BatchableContext bc, List<User> records){
         List<User> userList = new list<User>{};

         for(User InactiveUser : records){
             InactiveUser.IsActive = false;
             userList.add(InactiveUser);
         }
         update userList;
     }

     global void finish(Database.BatchableContext bc){
         // execute any post-processing operations
     }
}
VinayVinay (Salesforce Developers) 
Hi Jeff,

Try below 
[SELECT Id FROM User WHERE IsActive = TRUE AND Id NOT IN (SELECT UserId FROM LoginHistory WHERE LoginTime = LAST_N_DAYS:60)];

Snippet:
public class usersclass implements Schedulable {
    public void execute(SchedulableContext context) {
        User[] selectedUsers = [SELECT Id FROM User WHERE IsActive = TRUE AND Id NOT IN (SELECT UserId FROM LoginHistory WHERE LoginTime = LAST_N_DAYS:30)];
        for(User record: selectedUsers) {
            record.IsActive = false;
        }
        Database.update(selectedUsers, false);
    }
}

Thanks
Jeff Bryant 16Jeff Bryant 16
It looks like that will work but now I'm getting 
System.DmlException: Update failed. First exception on row 8 with id 0050Z000008dRt8QAE; first error: FIELD_INTEGRITY_EXCEPTION, You cannot deactivate this guest user because it's a guest user of an active community.: Active: [IsActive]

is there anyway to bypass community users? maybe check is isPortalEnabled = true?
VinayVinay (Salesforce Developers) 
Yes, you can try that and check.

 https://salesforce.stackexchange.com/questions/74186/disabling-community-user-in-community-visualforce-page

Hope this helps...

Thanks
RituSharmaRituSharma
You may check IsPortalEnabled field. Alternatively, you may check  AccountId or ContactId fields. 
RituSharmaRituSharma
BTW, you may achieve this requirement using Scheduled-Trigger flow as well. Doing declarative way is always better.
Jeff Bryant 16Jeff Bryant 16
This is what is currently working for me, just thought I'd share it.



global class DeactivateUsers implements Database.Batchable<SObject>
{
       dateTime dt = date.today().addDays(-60);
    String pro1 = 'System Administrator';
    public String query = 'SELECT Name, LastLoginDate, Id, user.profile.name From User WHERE IsActive = true AND LastLoginDate <: dt AND user.profile.name <>: pro1 ';
    

    global Database.querylocator start(Database.BatchableContext bc)
    {
       return Database.getQueryLocator(query);
    }

    global void execute(Database.BatchableContext bc,List<User> records)
    {
        List<User> userList = new List<User>();
        
        for(User r : records)
        {
            User u = (user)r;
            userList.add(u);
        }
        
        if(userList.size() > 0)
        { 
            for(User usr : userList) { usr.isActive = false; }
        }
        update userList;
    }

    global void finish(Database.BatchableContext bc){}
}
 
Vinay BhongaleVinay Bhongale

Try below Query

Select id, Username, LastLoginDate, from User where IsActive = true and LastLoginDate != LAST_N_DAYS:30 and CreatedDate != LAST_N_DAYS:30