- Post History
- Subscribe to RSS Feed
- Mark as New
- Mark as Read
- Bookmark
- Subscribe
- Printer Friendly Page
- Report Inappropriate Content
11-10-2023 04:05 AM - edited 11-10-2023 05:08 AM
ServiceNow administrators often need to create new users and assign them the appropriate roles and group memberships. This can be a time-consuming process, especially if the user needs to be granted access to a large number of groups and roles.
To make this process easier, you can create a UI action to clone the roles and groups of one user to another user. This UI action can be added to the User form, so that it is easily accessible to administrators.
To create this UI Action, I have created an UI Page to use it as a Pop Up and a Script Include to process the request. Follow along to create one for yourself.
A. Script Include: To create a Client Callable Script Include,
- Navigate to System Definition > Script Includes.
- Click New.
- Enter a name: CloneUserProfileUtils
- Set the Client Callable to True.
- In the Script field, enter the following code and Save.
var CloneUserProfileUtils = Class.create();
CloneUserProfileUtils.prototype = Object.extendsObject(AbstractAjaxProcessor, {
cloneRolesGroups: function() {
var usr = this.getParameter("sysparm_usr");
var usr_ref = this.getParameter("sysparm_usr_ref");
var override_existing = this.getParameter("sysparm_override_existing") + "";
if (override_existing === 'true' && !gs.nil(usr)) {
var clr_roles = this.clearRoles(usr);
if (!clr_roles)
return "false";
var clr_grps = this.clearGroups(usr);
if (!clr_grps)
return "false";
}
if (!gs.nil(usr) && !gs.nil(usr_ref)) {
var cpy_grps = this.copyGroups(usr, usr_ref);
if (!cpy_grps)
return "false";
var cpy_roles = this.copyRoles(usr, usr_ref);
if (!cpy_roles)
return "false";
}
return "true";
},
clearRoles: function(usr) {
try {
var roleGr = new GlideRecord("sys_user_has_role");
roleGr.addQuery("user", usr);
roleGr.addQuery("inherited", false);
roleGr.query();
roleGr.deleteMultiple();
} catch (ex) {
gs.info("Role remove Error: " + ex);
return false;
}
return true;
},
clearGroups: function(usr) {
try {
var grpGr = new GlideRecord("sys_user_grmember");
grpGr.addQuery("user", usr);
grpGr.query();
gs.info("Grp RC: " + grpGr.getRowCount());
grpGr.deleteMultiple();
} catch (ex) {
gs.info("Group remove Error: " + ex);
return false;
}
return true;
},
copyRoles: function(usr, usr_ref) {
try {
var roleGr = new GlideRecord("sys_user_has_role");
roleGr.addQuery("user", usr_ref);
roleGr.addQuery("inherited", false);
roleGr.query();
while (roleGr._next()) {
var tgtRoleGr = new GlideRecord("sys_user_has_role");
tgtRoleGr.addQuery("user", usr);
tgtRoleGr.addQuery("role", roleGr.getValue("role"));
tgtRoleGr.query();
if (!tgtRoleGr.hasNext()) {
tgtRoleGr.initialize();
tgtRoleGr.setValue("user", usr);
tgtRoleGr.setValue("role", roleGr.getValue("role"));
tgtRoleGr.insert();
}
}
} catch (ex) {
gs.info("Role copy Error: " + ex);
return false;
}
return true;
},
copyGroups: function(usr, usr_ref) {
try {
var grpGr = new GlideRecord("sys_user_grmember");
grpGr.addQuery("user", usr_ref);
grpGr.query();
while (grpGr._next()) {
var tgtGrpGr = new GlideRecord("sys_user_grmember");
tgtGrpGr.addQuery("user", usr);
tgtGrpGr.addQuery("group", grpGr.getValue("group"));
tgtGrpGr.query();
if (!tgtGrpGr.hasNext()) {
tgtGrpGr.initialize();
tgtGrpGr.setValue("user", usr);
tgtGrpGr.setValue("group", grpGr.getValue("group"));
tgtGrpGr.insert();
}
}
} catch (ex) {
gs.info("Group copy Error: " + ex);
return false;
}
return true;
},
type: 'CloneUserProfileUtils'
});
B. UI Page: To create an UI Page, follow these steps
- Navigate to System UI > UI Pages.
- Click New.
- Enter a name for the UI page: clone_user_roles_groups
- In the Client Script field & HTML field, enter the following code and Save.
Client Script:
function continueOK() {
var gdw = GlideDialogWindow.get();
var user_tgt = gdw.getPreference('usr');
var user_ref = gel('user_ref').value;
var override_existing = gel('override_existing').value;
var ga = new GlideAjax("CloneUserProfileUtils");
ga.addParam("sysparm_name", "cloneRolesGroups");
ga.addParam("sysparm_usr", user_tgt);
ga.addParam("sysparm_usr_ref", user_ref);
ga.addParam("sysparm_override_existing", override_existing);
ga.getXMLAnswer(processResponse);
function processResponse(answer){
if(answer === 'true')
g_form.addInfoMessage("Roles and Groups cloned successfully.");
else
g_form.addErrorMessage("Roles and Groups clone failed.");
GlideDialogWindow.get().destroy();
}
}
function continueCancel() {
GlideDialogWindow.get().destroy();
}
HTML:
<?xml version="1.0" encoding="utf-8" ?>
<j:jelly trim="false" xmlns:j="jelly:core" xmlns:g="glide" xmlns:j2="null" xmlns:g2="null">
<g:evaluate var="jvar_usr" jelly="true">
var usr = RP.getWindowProperties().get('usr');
usr;
</g:evaluate>
<g:evaluate var="jvar_usr_disp" jelly="true">
var usr1 = RP.getWindowProperties().get('usr');
var usr_disp = "";
var usrGR = new GlideRecord("sys_user");
usrGR.addQuery("sys_id", usr1);
usrGR.query();
if (usrGR.next()) {
usr_disp = usrGR.getDisplayValue();
}
usr_disp;
</g:evaluate>
<br/>
<div class="alert alert-info">
<strong>Note:</strong> You should elevate to security_admin to copy security_admin role.
</div>
<g:ui_form>
<br/>
<table>
<tr>
<td style="width:25%">
<g:form_label>
Target User:
</g:form_label>
</td>
<td style="width:60%">
<b>${usr_disp}</b><br/>
</td>
</tr>
<tr>
<td style="width:25%">
<g:form_label>
Reference User:
</g:form_label>
</td>
<td style="width:60%">
<g:ui_reference name="user_ref" id="user_ref" query="active=true" table="sys_user" />
</td>
</tr>
<tr>
<td style="width:25%">
<g:form_label>
Override Existing Roles & Groups:
</g:form_label>
</td>
<td style="width:60%">
<g:ui_checkbox name="override_existing" id="override_existing" value="false"/>
</td>
</tr>
</table>
<div id="dialog_buttons" class="clearfix pull-right no_next">
<g:dialog_buttons_ok_cancel ok_id="submitData" ok="return continueOK()" ok_type="button" ok_text="${gs.getMessage('Clone')}" ok_style_class="btn btn-primary" cancel_type="button" cancel_id="cancelData" cancel_style_class="btn btn-default" cancel="return continueCancel()"/>
</div>
</g:ui_form>
</j:jelly>
- Navigate to System Definition > UI Actions.
- Click New.
- Enter a name: Clone Roles and Groups.
- Enter an Action name: clone_roles_groups_from_ref_user
- Set Show Insert: False, Show Update True, Client: True and Form context menu: True and Form link: True
- In the Condition field, enter: gs.hasRole('admin') && current.active == true
- In the onClick field, enter: cloneUser()
- In the Script field, enter the following code and Save.
function cloneUser() {
var dialogClass = GlideDialogWindow;
var dialog = new dialogClass("clone_user_roles_groups");
dialog.setTitle("Clone Roles & Groups");
dialog.setPreference("usr",g_form.getUniqueValue());
dialog.setWidth(800);
dialog.render();
}
Note: See the screenshots attached for quick reference.
Now, when you open a User record, you will see the Clone Roles and Groups form context menu and related link. To clone the roles and groups of another user, simply click this button and select the reference user and check Override existing to true if you want to delete existing roles and groups of target user.
This UI action can save you a lot of time and effort when creating new users and assigning them the appropriate roles and group memberships.
- 5,087 Views
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
This is super helpful ..thanks for sharing
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
Great job. Appreciate.
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
When I do this everything comes up as normal. However, when I click clone roles and groups under my user I get an error stating that the page you are looking for could not be found. Any ideas?
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
@Toon6543 Please check the UI Page name, it should be same in UI Action Script line number 3.
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
Thanks for your work on this. I'm having an issue, when I launch the action from a user record, it just takes me back to the list of users. It seems like the UI Action isn't launch the UI Page. If I go to the UI Page and click on 'try it', the page launches. I have checked syntax several times and everything matches. Thanks for your help.
clone_user_roles_groups
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
Hi, I have the same issue because I missed to add the "sys_user" as table for the UI Action.
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
Sir, you are amazing and you have just saved me so much time. Thank you!!