With the recent Salesforce’s announcement on end of life of permissions on profiles, permission sets and permission set groups are the future of user management. Permission Set Groups allow bundles of permissions to be assigned to a User. They fill the gap between monolithic Profiles and atomistic Permission Sets, which is nice.
Now imagine a task that is to bulk assign a permission set license to all users in a permission set group. Since a permission set license can only be associated to individual users, admins can only go to the specified permission set license in “Setup | Company Information” and assign users. However there is no easy way to create a list view to show all users within a particular permission set group. Thus, one has to find each individual user and link them to the license.
For example, I was recently looking into the Salesforce “Data Mask” product which requires a permission set license (called “Data Mask User”) to be granted to any user who needs to access it. While in practice it probably only needs a couple of users in the production org to do such a job, in sandboxes we might want to grant all admins to test things. In my current project setup, all admin users are sharing the same permission sets which are all grouped into a permission set group called “All Assigned to Admin”. Therefore the simple requirement here is to grant the “Data Mask User” permission set license to all users in this group.
To avoid such a tedious routine that needs to be done in every sandbox for every admin user, I decided to write some scripts to automate the job. Here is the code I came up after two iterations.
// Avoid duplicates
Set<Id> assignedUserIds = new Set<Id>();
PermissionSetLicense psl = [select Id, (select AssigneeId from PermissionSetLicenseAssignments) from PermissionSetLicense where MasterLabel = 'Data Mask User' limit 1];
for (PermissionSetLicenseAssign psla : psl.PermissionSetLicenseAssignments) {
assignedUserIds.add(psla.AssigneeId);
}
PermissionSetLicenseAssign[] saveAssignments = new PermissionSetLicenseAssign[] {};
PermissionSetGroup psg = [select Id, (select AssigneeId from Assignments) from PermissionSetGroup where DeveloperName = 'CXC_All_Assign_to_Admin' limit 1];
// Only active users can be assigned
Id[] userIds = new Id[] {};
for (PermissionSetAssignment psa : psg.Assignments) {
userIds.add(psa.AssigneeId);
}
Map<Id, User> activeUsers = new Map<Id, User>([select Id, IsActive from User where Id in :userIds and IsActive = true]);
for (PermissionSetAssignment psa : psg.Assignments) {
if (!assignedUserIds.contains(psa.AssigneeId) && activeUsers.keySet().contains(psa.AssigneeId)) {
saveAssignments.add(new PermissionSetLicenseAssign(AssigneeId = psa.AssigneeId, PermissionSetLicenseId = psl.Id));
}
}
insert saveAssignments;
The initial version did not check whether users are Active but that results in an error saying the permission set license cannot be assigned to a user that is not Active. The code also checked things to not assign the license to any users who already have it so it can be defensively executed many times in the same org.
I was quite happy with the result.
A couple of days later when I was playing around with ChatGPT, I decided to assign the bot such a task. Here was my question and the bot’s answer:

I was shocked after seeing the first couple of sentences. The tone shows so much confidence of the bot as it even has concrete steps of doing such as job with a point-and-click style and specifically tells you where to find certain settings and click on which buttons. How did I miss such a configuration setting I wonder? Then I followed the steps all the way until Step 5 where there is no permission set license I can select. I realised it didn’t know what it was suggesting from that point on.
Then I requested the bot to write some code to do this and here is the result:

I have to say the code is nicely structured with variables properly named, and it even follows the typical Apex style that it initiates list/set variables first, then queries certain objects, and do a DML. The comments help you understand what it is doing although in practice comments like this talking about “what” instead of “why” is generally a bad one. But under the bot context, it is totally fine and it shows its thought process in plain English.
It is not the right code though. It seems to have mixed up UserPermissioSetAssignment with the other object PermissionSetLicenseAssign which is the key object to link a permission set license to a user. Note that when a permission set group is assigned to a user, it is done via the “PermissionSetAssignment” object (there is no “PermissionSetGroupAssignment” object).
I can probably help enhance its learning by clicking on the “Thumbs down” icon. It’s a powerful tool. Although it cannot replace us doing our work, it can certainly help guide us where to check things. It’s a language tool which means it can’t actually login into a trial org and do experiments (but who knows what the future brings). What I need to do, as a human, is to draft some code (possibly with the bot’s sample template), execute it, analysing errors, and tweak the code with more iterations to achieve the goal.
Here is a quick reference ERD for Permission related objects:
