- Post History
- Subscribe to RSS Feed
- Mark as New
- Mark as Read
- Bookmark
- Subscribe
- Printer Friendly Page
- Report Inappropriate Content
10-23-2021 10:21 PM - edited 07-08-2023 05:48 AM
The enhanced version of this utility can be found here.
Use case:
1. Our delivery manager created 50+ reports for himself and now leaving the organization. These reports are now to be shared with the new delivery manager.
2. We are onboarding a new prod-ops team. This team needs to see many existing reports which are already created for different teams.
Problem:
We can't share multiple reports with user/users or group/groups. Not, at least without running a fix script or background script.
Fix:
A list UI action which can share multiple reports with multiple users and groups at once.
**The video doesn't show the UI action list after clicking on "Actions on select rows". Due to some reason it was not captured. Sorry for that. It will show a UI action named "Share with user/groups". You'll create this action as mentioned in next step.
You need to configure a UI action, UI page and script include to achieve this.
1. UI Action:
Script:
function processReports(){
var table = g_list.getTableName();
var records = g_list.getChecked();
var sysIds = records.split(',');
var totalRecords = sysIds.length;
var dialog = new GlideDialogWindow('shareBulkReports');
dialog.setTitle('Share Multiple Reports');
dialog.setSize(700, 600);
dialog.adjustBodySize();
dialog.removeCloseDecoration();
dialog.setPreference('sysparm_sysIds', records );
dialog.setPreference('sysparm_totalRecords',totalRecords);
dialog.render();
}
2. UI page:
Name : shareBulkReports
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">
<j:set var="jvar_report_sysIds" value="${sysparm_sysIds}"/>
<j:set var="jvar_report_count" value="${sysparm_totalRecords}"/>
<div style="text-align:center;">
<h4>Sharing ${jvar_report_count} reports</h4>
</div>
<script>
addLoadEvent( function() {
var tabs = new GlideTabs2("tabs2_section", gel("rules_span"), 0, '');
tabs.activate();
show("rules_span");
});
</script>
<g:inline template="tabs2.xml" />
<div style="margin:20px">
<TABLE width="100%" cellSpacing="0" cellPadding="0" border="0">
<TR>
<TD valign="top">
<!-- tabstrip for tabs -->
<div class="tabs2_strip" id="tabs2_section">
<!-- hack for IE bug when tab strip causes a horizontal scroll bar to appear -->
<img src="images/s.gifx" alt="" height="1px" width="1px" style="margin-right: 0px;" />
</div>
</TD>
</TR>
<TR>
<TD align="center">
<span id="rules_span" style="display:none;border-top: 1px solid black; padding-top: 5px; margin-top: -7px;">
<!--Tab 1-->
<div id="section_tab.1" class="tabs2_section" tab_caption="Groups" tab_caption_raw="Groups">
<div id="groupsTab">
<g:evaluate>
//Get all groups
var grGroup = new GlideRecord('sys_user_group');
grGroup.addQuery('active', true);
grGroup.orderBy('name');
grGroup.query();
</g:evaluate>
<TABLE>
<TR>
<TD>
<!-- Include the 'ui_slushbucket' UI macro -->
<g:ui_slushbucket name="sbGroup" left_header="Groups" right_header="Selected">
<j:while test="${grGroup.next()}">
<option value="${grGroup.sys_id}"> ${grGroup.name} </option>
</j:while>
</g:ui_slushbucket>
</TD>
</TR>
</TABLE>
</div>
<div id="1_spacer" style="display: none; margin-bottom: 1px;" glide="true"></div>
</div>
<!--Tab 2-->
<div id="section_tab.2" class="tabs2_section" tab_caption="Users" tab_caption_raw="Users">
<div id="userstab">
<g:evaluate>
//Get all Users
var grUser = new GlideRecord('sys_user');
grUser.addQuery('active', true);
grUser.orderBy('name');
grUser.query();
</g:evaluate>
<TABLE>
<TR>
<TD>
<!-- Include the 'ui_slushbucket' UI macro -->
<g:ui_slushbucket name="sbUser" left_header="Users" right_header="Selected">
<j:while test="${grUser.next()}">
<option value="${grUser.sys_id}"> ${grUser.name} </option>
</j:while>
</g:ui_slushbucket>
</TD>
</TR>
</TABLE>
</div>
<div id="2_spacer" style="display: none; margin-bottom: 1px;" glide="true"></div>
</div>
</span>
<div id="tabs2_spacer" style="visibility: hidden;"/>
</TD>
</TR>
<TR>
<TD align="right">
<!-- Include the 'dialog_buttons_ok_cancel' UI macro -->
<g:dialog_buttons_ok_cancel ok="return onContinue()" cancel="return onCancel()" ok_type="button" cancel_type="button"/>
</TD>
</TR>
</TABLE>
</div>
</j:jelly>
Client Script:
//Process OK
function onContinue()
{
try {
//Get user selection
var groups = sbGroup.getValues(sbGroup.getRightSelect()); //store values as string
var users = sbUser.getValues(sbUser.getRightSelect());
var reports = '${JS:sysparm_sysIds}';
var count = '${JS:sysparm_totalRecords}';
//Ensuring that at least one user or groups is selected
if (groups != "" || users != "") {
//Share the reports to selected groups and users
var ajax = new GlideAjax('shareBulkReports');
ajax.addParam('sysparm_name', 'shareReport');
ajax.addParam('sysparm_groups', groups);
ajax.addParam('sysparm_users', users);
ajax.addParam('sysparm_reports', reports);
ajax.getXMLAnswer(getStatus);
} else {
alert("At least one group or user must be selected");
return;
}
} catch (err) {
alert(err);
}
function getStatus(answer) {
if (answer == "success") {
alert(count + " " + "Reports are shared with" + " " + users.length + " " + "users and" + " " + groups.length + " " + "groups successfully");
} else {
alert(answer);
}
}
GlideDialogWindow.get().destroy();
}
//Process Cancel
function onCancel() {
GlideDialogWindow.get().destroy();
}
3. Script Include:
Name : shareBulkReports
var shareBulkReports = Class.create();
shareBulkReports.prototype = Object.extendsObject(AbstractAjaxProcessor, {
shareReport: function() {
var userList = this.getParameter('sysparm_users'); //sys_ids of users as string passed via UI action
var groupList = this.getParameter('sysparm_groups'); //sys_ids of groups as string passed via UI action
var reportList = this.getParameter('sysparm_reports'); //sys_ids of reports as string passed via UI action
var answer;
var reportArr = reportList.split(','); //Converting string to array
//Share report with Groups
if (groupList) {
var groupArr = groupList.split(',');//Converting string to array
try {
var i = 0;
while (i < groupArr.length) {
var j = 0;
var grReportGroups = new GlideRecord('sys_report_users_groups');
while (j < reportArr.length) {
grReportGroups.newRecord();
grReportGroups.setValue('group_id', groupArr[i]);
grReportGroups.setValue('report_id', reportArr[j]);
grReportGroups.insert();
j++;
}
i++;
}
answer = "success";
} catch (err) {
answer = err;
}
}
//Share reports with Users
if (userList) {
var userArr = userList.split(','); //Converting string to array
try {
var k = 0;
while (k < userArr.length) {
var l = 0;
var grReportUsers = new GlideRecord('sys_report_users_groups');
while (l < reportArr.length) {
grReportUsers.newRecord();
grReportUsers.setValue('user_id', userArr[k]);
grReportUsers.setValue('report_id', reportArr[l]);
grReportUsers.insert();
l++;
}
k++;
}
answer = "success";
} catch (err) {
answer = err;
}
}
return answer;
},
type: 'shareBulkReports'
});
Or you can simply download attached xml and upload in your instance. It contains all three configurations.
I am not a pro developer, so please do suggest if you see any mistakes in the script. 🙂
Don't forget to mark helpful and bookmark the article for future reference.
- 8,957 Views

- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
This works GREAT and is exactly what I was looking for! Thank you!
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
Good work, thanks for sharing.
Adding search for users/groups on the UI Page would have been a bang.

- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
this is awesome - thank you!
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
Hi Jagjeet,
It Is working fine but we could see that one issue, we can see empty user id entries are creating in the user id column.
actully i shared to two reports it is showing 4 with empty records.
Thanks,
Shrinivasprasad
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
Unfortunately aint working for me... It stucks on loading the screen to share the reports...

- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
Its didnt work form, I follow the all steps. Getting below pop up while i sharing to users or group. what could be the issue?
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
@Community Alums @Julian12 @shrinivasprasad I am sorry for the issues you are facing while getting it to work. I'm working on a newer version of it with more features.
I'd release it probably by next week for general use. The package would include a custom workspace designed to manage dashboards and reports in easy way. Stay tuned!

- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
Where in the script(s) is the 'user' field on the report (sys_report) record set to 'group'?
I've set this up and it is working to share the report with the specified users/groups, but the User field on the report record still has the sys_id of the report creator (as if the report record is still shared with "Me").
This is causing the report to not appear for the users it is shared with under the "Group" tab on the report landing page. Instead, it is stating the number of reports removed due to security constraints (e.g. if I share four reports and two of them have 'group' in the User field and two have the sys_id of the creator, it display two but will also state that two reports have been removed due to security constraints).

- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
Depending on which Table the reports are created from, if the User(s)/Group member(s) you share with do not have the necessary role to view the table data you're going to see the 'security constraints' message. You can also use 'Report view' ACLs to make table data available to users without the necessary role so they can see data in the Report (even though they don't have access to the Table).
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
I would agree with that assessment in most cases. However, in this case the users have the appropriate roles. When I go into the affected report and simply change the sharing radio button to groups/users, I see the groups that were set by the script within the UI action, then save the report and all is well (impersonating the user shows that they can now see the report).
It just seems like the "group" setting is not being set on the report record. All else seems to be happening as expected.
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
gonna download this now and give it a try- we are working on cleaning up our 'published' reports to share to snc_internal role instead of unsecured URL- hoping your solution does roles as well as groups/users etc. If not- consider it a suggestion for enhancement....
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
Same experience as the one Julian12 reported, gets stuck at the "Share multiple reports" popup with loading.
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
@JagjeetSingh I believe Julian12 and I are seeing the issue not because its not working but its a delay because I suspect the groups and users took too long to load. is there a way to optimize? I waited for about 102 seconds and it actually loaded.
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
@JR1 @Adam43 @Gordon Manee @Suraj P S @Julian12 @shrinivasprasad I've released the latest version of this utility as an app. Have a look here.