Share reports in bulk || Multiple groups & Multiple users at once
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.
https://www.servicenow.com/community/platform-analytics-articles/share-reports-in-bulk-multiple-groups-amp-multiple-users-at-once/ta-p/2300278