I recently read a forum post on a Linkedin Salesforce group asking about blocking out User access to a Salesforce organization during regular maintenance or code deployment windows.
It is a best practice for Salesforce or any business system to go down when important work is being done on the back end, and yet there does not appear to be an easy way to do so as an Admin User.
I discovered that Salesforce actually does have a recommended solution to this, but it is buried deep in the Salesforce Development Lifecycle Guide under the “Using Profiles to Control Maintenance Updates” section:
If your organization includes many profiles, use the following strategy for setting up a maintenance window:
1. Create a new Profile named Maintenance with all login hours locked out.
2. Use the Data Loader to extract and save a mapping of Users and their User Profiles.
3. At the beginning of the maintenance window, use the Data Loader to change all User Profiles except the Administrator’s to the Maintenance profile.
- Note that it is very important to leave login access with the Administrator because otherwise all Users could remain locked out of the system indefinitely. If any integrations are going to run during the maintenance window, the integration User should also not be locked out.
4. At the end of the maintenance window, use the Data Loader to reload the Users with their original Profiles.
That sounds easy enough, but instead of using the Data Loader to save and reload every User’s Profile, how about we use the Developer Console?
First, we create the Maintenance profile and block out all login hours.
Next, we need to gather all the Users and their current Profile IDs by running code in the Developer Console.
For this example, I am going to have the mapping output as a Map object in Apex so that I can easily copy-and-paste the code later.
We also want to specifically exclude System Admins from the blocking, but feel free to exclude any other Profile or user names in the SOQL statement when you generate this map. In this example, I exclude my own User ID.
String s = 'Map<Id, Id> profilesToUsers = new Map<Id,Id>{'; boolean isFirst = true; for (User u : [SELECT Id,ProfileId FROM User WHERE IsActive = true AND Profile.Name != 'System Administrator' AND id !=: UserInfo.getUserId()]){ if (isFirst) isFirst = false; else s+=','; s += '\'' + u.id + '\' => \'' + u.ProfileId + '\''; } s += '};'; System.debug(s);
After you run the code, you should get a debug line that looks simular to this:
Map<Id, Id> profilesToUsers = new Map<Id,Id>{'005U0000000GoSIIA0' => '00eU0000000qrqtIAA','005U0000000GoSNIA0' => '00eU0000000qrqsIAA','005U0000000GoS8IAK' => '00eU0000000qrqvIAA'};
Save this line. You will need to restore your Users’ Profiles.
When you are ready to begin your maintenance window, run this code in the Console to switch everyone to the Maintenance profile. Again, it is very important that you exclude Admins from the lockdown. If you lock every User out of your system, then no one will be able to unlock them later on.
Profile maint = [SELECT id FROM Profile WHERE Name = 'Maintenance']; List<User> userList = [SELECT id FROM User WHERE IsActive = true AND Profile.Name != 'System Administrator' AND id !=: UserInfo.getUserId()]; for (User u : userList) u.ProfileId = maint.id; update userList;
Now all of your Users should be under the Maintenance profile and will not have access to your Salesforce org.
When you are done and want to switch your users back to their original Profiles, use the map you outputted earlier as the first line in this block of code:
Map<Id, Id> profilesToUsers = new Map<Id,Id>{'005U0000000GoSIIA0' => '00eU0000000qrqtIAA','005U0000000GoSNIA0' => '00eU0000000qrqsIAA','005U0000000GoS8IAK' => '00eU0000000qrqvIAA'}; List<User> userList = [SELECT id FROM User WHERE IsActive = true AND Profile.Name != 'System Administrator' AND id !=: UserInfo.getUserId()]; for (User u : userList) u.ProfileId = profilesToUsers.get(u.id); update userList;
And now everyone is back to where they were before the maintenance window.