Automate User Creation and Permission Set Group Assignment Using a Custom Metadata Type Mapping

Eliminate the manual steps of creating Salesforce users based on a case or form submission. Let Salesforce do the work for you. Use flow to automate the user creation and permission set group assignment based on a selected user persona with the help of a custom metadata type mapping.

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

  • Learn how to configure a screen flow invoked from a quick action.
  • Learn how to use a custom metadata type to manage the profile | role | permission set group mapping for a user persona. Avoid “hardcoding” this information in your automation.
  • Learn how you can use community built flow actions – in this post, we will use NavigateToRecord and Update Screen to enhance the power of flow from UnofficialSF.
  • 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 variables, the purpose of a flow, what each flow element does, etc.

Business Use Case:  Addison Dogster is the system administrator at Universal Containers. Part of her job is user maintenance, creating new users, assigning permission set groups and permission sets. Addison has worked on creating some cool automation but how about automating these routine, boring user maintenance tasks so she can work on building new automation?

Solution: Addison needed a way to map each user persona to a profile, role and permission set group so she doesn’t need to hardcode all the various scenarios in her flow or need to refactor the flow every time a new user persona is introduced or needed to be modified. This will be handled via custom metadata type (CMDT). By having this mapping in a CMDT, Addison can maintain user personas in a pinch and keeping the flow in tact. Addison’s motto is “Work Smart, Not Hard.”

Note: You can extend this mapping to include public groups, queues, etc.

Solution includes:

  • My Domain needs to be enabled in the org to use the local action component from the UnofficialSF. This blog post will not cover enabling My Domain in your org.
  • Custom fields to capture the user’s request information on the custom object called User Request. Note: You can add these fields to the Case object if you are using case management to manage new user requests. You need to create fields to store the user’s first name, last name, email address and requested user persona. For your use case, you may need to capture additional information.
  • One custom metadata types for the user persona mapping to profile, role and permission set group.
  • The users running this flow will need the system permission to manage users.
  • A flow that is initiated by an Approve quick action on the record page that looks up the User Persona to Profile | Role | Permission Set Group mapping, the looks up the profile id, role id, permission set group id using a Get Records flow element using the profile name, role name and permission set group API name (no hardcoding!). It then creates the user, assigns the newly created user to a permission set group, takes the user back to the user request record upon the flow completion and refreshes the page.

ApprovetheNewUserRequestFlowView image full screen

What, what is a custom metadata type? Read the section called “What’s a custom metadata type?” in this previous blog post.

Steps: 

1.Create a new text field on the User Request object (or the object of your choosing) to store the user’s first name (First_Name__c) and last name (Last_Name__c), a new email field to store the user’s email address (Email__c) and a new picklist field that contains the user persona (User_Persona__c).

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

2. Create the Custom Metadata Type. This CMDT will store the profile, role and permission set group associated to each user persona. In Classic, go to Setup | Develop | Custom Metadata Types | New or in Lightning, go to Setup | Custom Code | Custom Metadata Type | New. Let’s call this “Persona to Profile | Role | PSG Mapping.”

View image full screen

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

A. Create custom text fields called Permission Set Group API Name (Permission_Set_Group_API_Name__c), Profile Name (Profile_Name__c)Role Name (Role_Name__c) and User Persona (User_Persona__c).

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

B. Create custom metadata type records, to hold the user persona and associated profile name, role name and permission set group API name. Example below.

View Image Full Screen

3. Install the NavigateToRecord and Update Screen components from UnofficialSF. This allows you to take the user back to a record after the flow is finished and eliminates the “Flow is finished” message as the last flow step.

I highly recommend installing and testing this in a sandbox first. Don’t just install it directly to Production. To ensure you are installing in a sandbox, always make sure the URL is test.salesforce.com.

Right-click on the link and do a copy link address. Paste “/packaging/installPackage.apexp?p0=xxxxxxxxxxxxxxxxxx” at the end of the URL (where xxxxxxxxxxxxxxxxxx is the Id of the package installation). This will automatically install the package in your sandbox or production, whereever you are logged into.

4. Let’s create the flow that is initiated by an Approve quick action on the record page that looks up the User Persona to Profile | Role | Permission Set Group mapping, the looks up the profile id, role id, permission set group id using a Get Records flow element using the profile name, role name and permission set group API name (no hardcoding!). It then creates the user, assigns the newly created user to a permission set group, takes the user back to the user request record upon the flow completion and refreshes the page. 

ApprovetheNewUserRequestFlow

For those using Salesforce Classic, flow can be found in Create | Workflows & Approvals | Flows. In Lightning Experience, it is found under Process Automation | Flows. Click on “New Flow.” Select Screen Flow. Click on the Create button.

A. Let’s create our flow resources. Go to the Manager tab, click on the New Resource button.

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

Create another record variable called “recordId.” In Summer ’20, when you create a record variable, rather than a text variable, you will have access to all the data for that record without needing to do a Get Records to retrieve the record data. Note: recordId is a reserved variable name that passes the record Id from a quick action or lightning record page.

  • Resource Type: Variable
  • API: recordId
  • Data Type: Record
  • Object: User Request (or the object you create the fields from Step 1)

Your completed variable should look like this.

recordId

Now, let’s create a formula variable called “AliasFormula.” The alias field on the user object is not unique. However, it is limited to 8 characters. We will set the alias to the first character of the user’s first name and the user’s last name with today’s month and day, but limited to 8 characters. If you don’t limit this, your flow will fail.

  • Resource Type: Formula
  • API: AliasFormula (I like end my formulas with “XXXXFormula”)
  • Data Type: Boolean
  • Formula: LEFT(LEFT({!recordId.First_Name__c}, 1)+{!recordId.Last_Name__c}+TEXT(MONTH(today()))+ TEXT(DAY(today())),8) [Note: {!recordId} is the recordId. Click on > to access the record fields.]

Your completed variable should look like this.

AliasFormula

We need to another  formula variable called “UsernameFormula.” The username takes the format of the user’s email+value that makes the username unique across all Salesforce orgs. In this example, Addison adds “.jen” at the end of their email address for their username

  • Resource Type: Formula
  • API: UsernameFormula (I like end my formulas with “XXXXFormula”)
  • Data Type: Text
  • Formula: {!recordId.Email__c}+”.jen” [Note: {!recordId} is the recordId. Click on > to access the record fields.]

Your completed variable should look like this.

UsernameFormula

B. First, drag the Get Records flow element to the canvas so we can query the Persona to Profile | Role | PSG Mapping custom metadata object for the profile, role and permission set group associated to a user persona.

  • Label: Get the Profile | Role | PSG Mapping for the User Persona
  • Object: Persona to Profile | Role | PSG Mapping
  • Filter the Persona to Profile | Role | PSG Mapping Records
    Records by User_Persona__c Equals {!recordId.User_Persona__c}.
  • How Many Records to Store: Only the first record
  • How to Store Record Data: Automatically store all fields

Best practice tip: Provide a description so you and other/future admins know what this flow element is used for.

Your completed Get Records flow element looks like this.

View image full screen

C. Drag another Get Records flow element to the canvas to look up the Profile object to find the profile Id using the profile name from the CMDT mapping.

  • Label: Get the Profile Id
  • Object: Profile
  • Filter the Profile Records by Name Equals {!Get_the_Profile_Role_PSG_Mapping_for_the_User_Persona.Profile_Name__c}
  • How Many Records to Store: Only the first record
  • How to Store Record Data: Automatically store all fields

Best practice tip: Provide a description so you and other/future admins know what this flow element is used for.

Your completed Get Records flow element looks like this.

View image full screen

D. Drag another Get Records flow element to the canvas to look up the Role object to find the role Id using the role name from the CMDT mapping.

  • Label: Get the Role Id
  • Object: Role
  • Filter the Role Records by Name Equals {!Get_the_Profile_Role_PSG_Mapping_for_the_User_Persona.Role_Name__c}
  • How Many Records to Store: Only the first record
  • How to Store Record Data: Automatically store all fields

Best practice tip: Provide a description so you and other/future admins know what this flow element is used for.

Your completed Get Records flow element looks like this.

ApprovetheNewUserRequest-RoleGetRecordsView image full screen

E. Drag another Get Records flow element to the canvas to look up the Permission Set Group object to find the permission set group Id using the permission set group developer name from the CMDT mapping.

  • Label: Get the PSG Id
  • Object: Permission Set Group
  • Filter the Permission Set Group Records by DeveloperName Equals {!Get_the_Profile_Role_PSG_Mapping_for_the_User_Persona.Permission_Set_Group_API_Name__c}
  • How Many Records to Store: Only the first record
  • How to Store Record Data: Automatically store all fields

Best practice tip: Provide a description so you and other/future admins know what this flow element is used for.

Your completed Get Records flow element looks like this.

ApprovetheNewUserRequest-PSGGetRecordsView image full screen

F. Drag another Create Records flow element to the canvas to create the new user.

  • Label: Create a New User
  • How Many Records to Create: One
  • How to Set the Record Fields: Use separate resources, and literal values
  • Object: User
  • Set fields:
    • Alias: {!AliasFormula}
    • Email: {!recordId.Email__c}
    • EmailEncodingKey: ISO-8859-1
    • FirstName: {!recordId.First_Name__c}
    • LanguageLocaleKey: en_US
    • LastName: {!recordId.Last_Name__c}
    • LocaleSidKey: en_US
    • ProfileId: {!Get_the_Profile_Id.Id}
    • TimeZoneSidKey: America/New_York
    • UserRoleId: {!Get_the_Role_Id.Id}
    • Username: {!UsernameFormula}

Best practice tip: Provide a description so you and other/future admins know what this flow element is used for.

Your completed Create Records flow element looks like this.

ApprovetheNewUserRequest-CreateRecordView image full screen

G. Drag another Create Records flow element to the canvas to assign the permission set group to the newly created user.

  • Label: Assign the User to the PSG
  • How Many Records to Create: One
  • How to Set the Record Fields: Use separate resources, and literal values
  • Object: Permission Set Assignment
  • Set fields:
    • AssigneeId: {!Create_a_New_User}
    • PermissionSetGroupId: {!Get_the_PSG_Id.Id}

Best practice tip: Provide a description so you and other/future admins know what this flow element is used for.

Your completed Create Records flow element looks like this.

ApprovetheNewUserRequest-PSGCreateRecordsView image full screen

H. Drag an Action flow element to the canvas. Search for and select the navigatetoRecord component.

  • Label: Go to the record
  • Set Input Values:
    • Object: User_Request__c (Or the object that you configured the user request fields in). Toggle to Include.
    • Record Id: {!recordId.Id}. Toggle to Include.
    • View or Edit? View. Toggle to Include.

Best practice tip: Provide a description so you and other/future admins know what this flow element is used for.

Your completed navigateToRecord flow element looks like this.

ApprovetheNewUserRequest-NavigateToRecordView image full screen

I. Drag another Action flow element to the canvas. Search for and select the UpdateScreen component.

  • Label: Refresh the screen
  • Set Input Values:  Record Id: {!recordId.Id} Toggle to Include.

Best practice tip: Provide a description so you and other/future admins know what this flow element is used for.

Your completed UpdateScreen flow element looks like this.

ApprovetheNewUserRequest-UpdateScreenView image full screen

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

K. Connect the flow elements and fault connectors to match the below…

ApprovetheNewUserRequest-Connectors

L. Save/Save As and provide the following properties.

Best practice tip: Provide a description so you and other/future admins know what this flow is used for.

ApprovetheNewUserRequest-FlowProperties

Summer ’20 Release or after] M. Before you activate your flow, test this by using the Debug button. As an input variable, you can select the recordId as the input.

ApprovetheNewUserRequest-Debug

N. Click the “Activate” button.

5. Create a quick action that invokes the flow. In Setup | go to Object Manager | User Request, select Buttons, Links, and Actions and click on New Action to create the quick action. Configure it to match the image below.

ApproveQAView image full screen

6. Lastly, add the quick action to the page layout.

7. Any users who want to have approve these user requests need the following two permissions: Run Flows and Manage Users. These can be granted in a permission set and assigned to the user if the user does not already have these permissions in their profile.

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

Deployment Notes/Tips:

  • Flows, custom metadata type object, fields, quick action and page layout can be deployed to Production in a change set (or can be deployed using a tool such as Metazoa’s Snapshot).
  • Don’t forget to deploy the profile(s) that need access to view the new fields via FLS.
  • You will find the flows in a change set under the Flow Definition component type.
  • Custom metadata type records are also deployable under the Custom Metadata Type component type.
  • The custom metadata type objects can be found in a change set under the name of the custom metadata type object.
  • Activate the flow post deployment as flows deploy inactive in Production, unless you have opted in on the Process Automation Settings screen, to “Deploy processes and flows as active.” NOTE: With this change, in order to successfully deploy a process or flow, your org’s Apex tests must launch at least 75% of the total number of active processes and active autolaunched flows in your org.

Source: https://jenwlee.com/2020/07/13/automate-user-creation-and-permission-set-group-assignment-using-a-custom-metadata-type-mapping/

Leave a Comment