How To

Automated Cleanup When User Is Deactivated -Remove User from Permission Sets


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

  • Automate the removal of permission sets from a deactivated user.
  • Understand the structure of permission set and permission set assignments.
  • Use process builder to invoke flow.
  • Strengthen your flow from faulting by adding decision elements.
  • Provide descriptions, where provided, in Salesforce. This may be tedious step, I know, but your future self will thank you when you are trying to remember what you configured or assist other/future admins when troubleshooting or enhancing what was built. This includes providing the purpose of a process builder, flow, variable, etc.

When a user is deactivated, there is work needed to clean up the org of references to this user. When I look a permission set, I only want to see active users assigned. Having inactive users along with active users is clutter to me. And if you accumulate deactivated users over time, then it becomes a bigger chore to clean them up manually. When a user is deactivated, it would be great to just remove the user from everything.

Now, with powerful automation tools like process builder and visual workflow, automating this type of cleanup is doable, for the most part, using clicks, and a little bit of code.

Before we continue on, let’s first take a look at the relationship of permission sets.


When you create a permission set, it creates a new record in the PermissionSet object that has the security settings associated to given permission set.

There is a separate object called PermissionSetAssignment that holds records of the user assignment to a permission set. In the permissionsetassignment record, you have the Id of the PermissionSetAssignment record, the permissionsetID (Id of the Permission Set from the PermissionSet object) and the AssigneeId (this is the user assigned to the permission set).

In theory, we should have been able to query the permission set assignment records associated to the user and delete them. However, Salesforce assigns system permission sets to users unbeknownst to us. I kept getting the nasty flow error when trying to do a delete on the records I queried. It wasn’t until after opening a case with Salesforce support that I learned about these systematic permission sets that are assigned. So, in order for this process to work, we need to query the permission set assignment records where the  IsOwnedByProfile is false. Since we can’t perform SOQL queries in flow, we need to write a little apex, invocable method, to do this legwork for us and then pass the query result back into our flow to take action on.

We use process builder to execute the process when a change is made on a user record, extend to flow for the assist on deleting permission assignment records, which process builder cannot.

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 also have a blog post on how to automatically remove deactivated users from public groups or queues.

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 permission sets. Although the removal of a user from permission sets is on the deactivated user checklist, sometimes, it may be overlooked due to human error. 

Solution: While this can be handled via a trigger, Addison Dogster is able to solve this using process builder, visual workflow and a little tiny bit of help from apex invocable method. (Much gratitude to Doug Ayers for the developer assist in the apex invocable method and test class!)



Quick Steps:

1.First, we need to create the apex invocable method to query the non-system permission set assignment records associated to the user. For the purposes of this post, we are only focusing on the step-by-step to automate a process, not apex class development. You can install the apex class and test class via the link below:

Note: If you are installing into a sandbox organization you must replace the initial portion of the URL with

2. Now, let’s create the visual workflow (Create | Workflows & Approvals | Flows in Salesforce Classic or Process Automation | Flows in Lightning Experience).

This flow will lookup and see if the user is associated to any non system permission sets, determine if there are any records found, and if yes, then delete the associations.


A. We will create 1 variable upfront, which will store the user ID.


Best practice tip: Don’t forget to provide a description so you and other/future admins know what these variables are used for.

B. Create 1 SObject Collection Variables, to hold the collection of permission set assignment records where the user matches the assigneeId


Best practice tip: Don’t forget to provide a description so you and other/future admins know what these sobject collection variables are used for.

C. Locate and bring into the canvas under Apex, the GetUserPermissionSetInvocable, which will lookup the PermissionSetAssignment object where the AssigneeId is the user ID passed from process builder. Once it finds the PermissionSetAssignment records where IsOwnedByProfile is false, it will store it in the sObject collection variable sCollectionUserPermissionSet.

The input User ID source is the variable (varUserID) we created earlier.


Tab over to the Outputs tab, select the Permission Set Assignments source and the target is the sObject collection variable, sCollectionUserPermissionSet.


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

D. Now, we need to use a Decision flow element to determine whether records were found in the Fast Lookup to continue on with the process.

We want to decide whether the sobject collection sCollectionUserPermissionSet has records so it is set to {!sCollectionUserPermissionSet} is null {!GlobalConstant.False}, which means that the sobject collection is not null.


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

E. We now need a Fast Delete flow element to delete the records found in the sobject collection sCollectionUserPermissionSet.


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

F. Draw the other connectors between the flow elements.


G. Add the subflow Send Flow Fault Email. For instructions on how to create this, go to Step 2 of blog post: Maximize Maintainability With Process Builder and Componentized Visual Workflow.

H. Set your flow starting point. And connect the flow elements and the fault connectors to match the below…

Can’t seem to get the fault connector to appear? Create a temporary flow element (circled below), draw your first connector to that temporary flow element. Then, draw another connector to the send element. This connector has the word “FAULT” in it.

Once that is completed, delete the temporary flow element you created. This is the end result.


I. Click on the Save button and provide the following information

Best Practice Tip: Don’t forget to provide a description so you and other/future admins know what this visual workflow is for.


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

J. Click the “Close” button.

K. On the flows screen, activate the flow.


2. Lastly, we will create a process using process builder that will run when a user is deactivated and will invoke the flow created in Step 2. Create a process builder (Create | Workflows & Approvals | Process Builder in Salesforce Classic or Process Automation | Process Builder in Lightning Experience).

Note: The screenshot shows two additional immediate action. The two 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.

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.DeactiveUsersProcessBuilder-Object.JPG

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.”

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.deactiveusersprocessbuilder-criterianode

D. Next, we want to set the immediate action to invoke the flow we created in Step 2.

Action Type: Flows

Action Name: InvokeFlowRemovePermSets

Flow: Remove Permission Sets from a Deactivated User (this was the flow we activated in Step 2)

Set Flow Variables: We want to send the User’s ID in the variable varUserID.

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 associated permission sets 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 one or more permission sets.
    • Confirm that the user is assigned to the permission set(s).
  2. Go to the user record, deactivate the user and save.
    • Confirm the user’s active field is unchecked.
    • Navigate to the permission set assignments.
    • Confirm that the user is no longer associated to any permission sets.

Deployment Notes/Tips:

  • The apex class, test class, process builder and visual workflow 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 and visual workflow components in a change set under the Flow Definition component type.
  • Activate the process builder and visual workflow as they are deployed as inactive into Production.

9 thoughts on “Automated Cleanup When User Is Deactivated -Remove User from Permission Sets

  1. Hi Jennifer!

    This is a great blog post. I’m an admin of an org with around 3,000 users so there tends to be a lot of clutter with inactive users. We’re trying to do clean up on roles & profiles and see if we can delete anything that isn’t used or combine similar things if they are only used by a few people. Is there any reason you couldn’t do this for roles as well? When you deactivate a user is there anyway to unassign their profile?


  2. You have to assign a user to a profile (required). In this case, i propose a custom profile with no permissions. Let’s call it “Not active.”. You can remove the user from the rolemail, since a user can have none or one role. I can write up a blog post for that.


  3. Hi Jenwlee,
    i want to update a record owner same as a contact owner when a record is created is it possible to do using process builder and a flow
    if yes please let me know the criteria i have to use in process builder
    could you please explain me briefly.

    Thanks in advance.


  4. Excellent post. Keep writing such kind of info on your
    page. Im really impressed by your site.
    Hi there, You’ve done a great job. I will definitely digg it and individually recommend to my friends.
    I’m confident they will be benefited from this site.


  5. Hi Jen,

    Thank you for laying out these steps so clearly. I was able to create the flow and process builder in my sandbox and run it successfully. My question now is: how can I also remove perm set licenses from deactivated users? It seems relatively straightforward to modify the flow for this purpose by looking up the Permission Set License Assignment object, but I’m not sure how to write the class that would query it.

    Samantha Lisk


  6. I would try it by looking up the permission set license assignment object and getting all records associated with the user and deleting them. You would only need apex as I did with the permission set assignment object if you run into an issue and for that, you will need to ask a developer. Sorry.


Comments are closed.