How To

Automated Cleanup When User Is Deactivated – Assign to an Inactive User Profile and Remove Role


Here are a few lessons learned from implementing this use case:

  • Automate the profile assignment and role removal of a deactivated user via process builder.
  • Use a custom label to store the profileID for the Inactive User profile versus hardcoding the ID in your process builder.


This blog post was inspired by Ashley Papp who posted this comment on one of my deactivate users post.


When a user is deactivated, there is work needed to clean up the org of references to this user. When you look at profiles and roles, you only want to see active users. Having inactive users along with active users is clutter to me, especially in an org that have a lot of users.  When a user is deactivated, it would be great to just remove the user from everything.

With process builder, automating this type of cleanup is doable, using clicks, no code.

Note: If your org has paid managed packages with user package licenses, refer to my blog post on automating the removal of managed package user licenses for a deactivated user. I have a blog post on how to automatically remove deactivated users from public groups or queues and remove the user’s assigned permission sets.

While you can remove the user from a role, the profile is a mandatory field. What we can in this case is create a new custom profile called Inactive User, cloning the read only standard profile, and removing all system permissions.

Note: If you org has different license types, i.e. Salesforce versus Salesforce Platform, you will need to create an Inactive User profile for each license type and in your process builder, check for the license type.

Process builder requires the profile ID to update the user record’s profile. However, it is not a best practice to “hardcode” an ID in process builder, flow, code, validation rule, etc. Why, you may ask?


The reason why you want to avoid hardcoding Salesforce IDs is that when the new profile is created in a sandbox, and then created in every sandbox leading up and including Production, that new profile’s Salesforce ID will not be the same. You will then need to update process builder’s reference of this hardcoded Salesforce profile ID in every sandbox or production and hence, have different versions of your process builders.

To avoid hardcoding the ID, you can use a custom label or custom setting. In this post, we will go the custom label route. To learn more about custom settings as an option, read my blog post Use Custom Settings in Process Builder.

Business Use Case: Addison Dogster is a system administrator at Universal Container. Addison noticed when performing a user audit review, that although user are deactivated in Salesforce, the user is still assigned to the same profile and role. Although the removal of a user from a profile and role is on the deactivated user checklist, sometimes, it may be overlooked due to human error.

Solution: Being an #AwesomeAdmin, Addison Dogster is able to solve this using process builder.

Quick Steps:

1.First, we need to create a new custom profile (Manage Users | Profiles in Salesforce Classic or Users | Profiles in Lightning Experience) called Inactive User.

Go to the standard Read Only profile, select the Clone link and name it “Inactive User.” Then go and manually remove all system permissions, access to objects, etc.

2. Create a custom label (Create | Custom Labels in Salesforce Classic or User Interface | Custom Labels in Lightning Experience).

First, we need to locate the Salesforce ID for the profile by looking at the URL when on the Inactive User profile. Copy the ID from the browser URL highlighted in yellow below.


You will notice that the ID when shown in Salesforce is the 15 character ID, which is case sensitive. To remove the case sensitivity, use the 18-character reference ID, which is case-safe.

Google “convert 15 to 18 characters” and one of the tools you can use is this one below.


Provide the following for the custom label information as below. For the value, you will paste the 18 character Salesforce ID from the tool above.

Note: The text put into the Categories field allows you to categorize the custom labels in your org for your own organization purposes. I like to note where I’m referencing the item in the label. In this case, I will be referencing this in Process Builder, so that’s what I have in the Categories field.


3. Lastly, we need to create a process builder (Create | Workflows & Approvals | Process Builder in Salesforce Classic or Process Automation | Process Builder in Lightning Experience).

Note: The screenshot shows three additional immediate action. The three action steps were to invoke the user removal from managed package licenses and associated permission sets from blog post on automating the removal of managed package user licenses for a deactivated user and blog post on automating the removal from public groups and queues and blog post on automating the removal from permission sets.

A. Set the process builder properties. We will call this process “Deactivate Users”, provide it a description and select this process to start when “A record changes.”


Best practice tips: Don’t forget to provide a description so you and other/future admins know what this process is used for.

B. We need to select “User” as the object and we want our process to run when a record is created or edited, click the “Save” button.


C. We need to specify the criteria node that needs to be met to then execute the flow. Let’s call out criteria “User is deactivated” which will execute when “conditions are met.”

Select the User record that started your process

We want this to run when the user’s active field has changed and the active field is set to false. Save the criteria node.


D. Next, we want to set the immediate action to update the record that started the process, with the profile ID to use the ID stored in the custom label we created in Step 2 and blank out the role ID.

Set the immediate actions to the below.

Action Type: Update Records

Action Name: Change Profile and Remove Role

Record Type: Select the user record that started your process

Criteria for Updating Records: No criteria—just update the records!

Set new field values for the records you update:

  • Profile ID formula $Label.Inactive_Profile_ID
  • Role ID Global Constant $GlobalConstant.Null

Since we are pulling the custom label, for the Profile ID field, we need to use a formula. In the formula window, click on System Variable


This will display a pop up, select $Label – this is where you can access custom labels configured in your org. They will be listed by their custom label name.


Once you locate the label name, in our case, it is Inactive Profile ID, select it and click on the Choose button.


Click on the “Use this Formula” field to save the formula sy



Add the next field value – Role ID. Since we want to blank it out, we are going to select Global Constant and then select $GlobalConstant.Null.

Save the immediate action.


The end result looks like this…



E. Click on the “Activate” button to activate the process.


Congrats, you made it to the end! You’ve implemented a process to automatically remove the role and change the profile to the Inactive User profile when a user is deactivated.

Now, before you deploy the changes to Production, don’t forget to test your configuration changes.

  1. Assign a user to a role and profile.
  2. Go to the user record, deactivate the user and save.
    • Confirm that the role is now blank and the profile is Inactive User.

Deployment Notes/Tips:

  • Manually clone the profile in Production off of the standard read only profile. Clear out all system permissions and object access.
  • The process builder and custom label can be deployed to Production in a change set (or can be deployed using a tool such as Dreamfactory’s Snapshot).
  • You will find the process builder component in a change set under the Flow Definition component type.
  • Update the custom label with the ID of the Inactive User custom profile.
  • Activate process builder as it is deployed as inactive into Production.