Report all workflows for which user "X" is the only approver

MarkD0256071013
Tera Contributor

We have a user who has offboarded. Today it was reported that there seem to be workflows for which he is the ONLY approver. Is it possible to report all the workflows that have only one approver, along with that user's ID / email?

 

It would also be good to be able to report all approval groups which have either no or a single member.

2 REPLIES 2

Robert H
Mega Sage

Hello @MarkD0256071013 ,

 

I'll start with answering your last question first: here is how you can get a report of all groups hat have one or zero members:

 

RobertH_0-1744735205113.png

 

Finding out in which workflows a person is the only approver is very tricky. There are so many ways in which a workflow can determine the approvers: they might be selected directly in the approval activity, or pulled from an approval group, or pulled from a related CI, from a decision table, calculated by a script, etc.

 

If your developers have consistently built all workflows using only approval groups then you could start by getting the list of groups with only 1 member (as shown above) and then check if the offboarded user is a member of some of them. Then fill up those groups with other people.

 

As a last resort you could look at recent approval records where that person was the approver. That could tell you which processes, and therefore which workflows, that user is linked to. But then checking if that person is the only approver would have to be an additional check on each of those workflows.

 

Meanwhile you could create a Delegation from that offboarded user to someone who has taken over their role, so that at least those approval requests do not get stuck.

 

Regards,

Robert

 

SasiChanthati
Giga Guru

Based on the use case you have provided, the below is the sample solution:

 

Find Approval Groups with Only One or No Members

The approval groups are just groups (sys_user_group), and their members are in the sys_user_grmember table.

Report: Groups with 0 or 1 Member

Use this GlideAggregate:

var ga = new GlideAggregate('sys_user_grmember');
ga.groupBy('group');
ga.addHaving('COUNT', 'user', '<=', '1');
ga.query();

while (ga.next()) {
var group = new GlideRecord('sys_user_group');
group.get(ga.getValue('group'));
gs.print('Group: ' + group.name + ' - Member Count: 1');
}

 

To include 0-member groups, you'll need to loop through all groups and compare against the sys_user_grmember table:

 

var allGroups = new GlideRecord('sys_user_group');
allGroups.query();

while (allGroups.next()) {
var memberCheck = new GlideRecord('sys_user_grmember');
memberCheck.addQuery('group', allGroups.sys_id);
memberCheck.query();

if (!memberCheck.hasNext()) {
gs.print('Group with NO members: ' + allGroups.name);
}
}

 

You can combine both into a single report if you want to generate a list of:

  • Groups with 0 or 1 members

  • Along with group name, sys_id, and member names/emails (if any)

Exporting/Reporting Options

  • Use Scheduled Jobs or Reports to run these regularly.

  • Add results to a custom table if you want history.

  • Send output to email or Slack/Teams notifications using integrations.

Task How

Workflows with only user X as approverQuery sysapproval_approver, group by sysapproval, count = 1
Approval groups with ≤1 memberQuery sys_user_grmember, group by group, having count ≤1
Approval groups with 0 membersLoop through sys_user_group and check if sys_user_grmember exists

 

We can use this script logic into a Scheduled Script Execution (Scheduled Job or fix scrip or background scrip) in ServiceNow, if we are using in scheduled job it can run regularly and alert your team of:

  1. Workflows where a single user (like the offboarded one) is the only approver

  2. Approval groups that have no or only one member

 

  • The sys_id of the offboarded user (we'll call it userSysId)

  • (Optional) An email address or group to send the results to

Create the Scheduled Script

  1. Go to System Definition > Scheduled Jobs

  2. Click New, then choose "Scheduled Script Execution"

  3. Name it something like: Detect Lone Approvers and Understaffed Groups

  4. Set Run to daily/weekly/etc. as needed

  5. Paste the script below into the Script field

(function() {
var userSysId = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxx'; // Replace with the offboarded user's sys_id

var loneApprovals = [];
var groupWarnings = [];

// PART 1: Find workflows where offboarded user is the ONLY approver
var approvalAgg = new GlideAggregate('sysapproval_approver');
approvalAgg.addQuery('approver', userSysId);
approvalAgg.groupBy('sysapproval');
approvalAgg.addHaving('COUNT', 'approver', '1');
approvalAgg.query();

while (approvalAgg.next()) {
var approvalId = approvalAgg.getValue('sysapproval');
var approval = new GlideRecord('sysapproval_approver');
if (approval.get('sysapproval', approvalId)) {
loneApprovals.push('Only approver: ' + approval.approver.name + ' on request: ' + approval.sysapproval.display_value);
}
}

// PART 2: Approval groups with only 1 member
var groupAgg = new GlideAggregate('sys_user_grmember');
groupAgg.groupBy('group');
groupAgg.addHaving('COUNT', 'user', '<=', 1);
groupAgg.query();

while (groupAgg.next()) {
var groupId = groupAgg.getValue('group');
var group = new GlideRecord('sys_user_group');
if (group.get(groupId)) {
groupWarnings.push('Group "' + group.name + '" has only one member.');
}
}

// PART 3: Approval groups with NO members
var allGroups = new GlideRecord('sys_user_group');
allGroups.query();

while (allGroups.next()) {
var memberCheck = new GlideRecord('sys_user_grmember');
memberCheck.addQuery('group', allGroups.sys_id);
memberCheck.query();
if (!memberCheck.hasNext()) {
groupWarnings.push('Group "' + allGroups.name + '" has NO members.');
}
}

// COMPILE OUTPUT
var body = '';
body += ' Lone Approver Warnings \n\n';
body += loneApprovals.length ? loneApprovals.join('\n') : ' No lone approvals found.\n';

body += '\n\n Group Membership Warnings \n\n';
body += groupWarnings.length ? groupWarnings.join('\n') : ' All groups have sufficient members.\n';

// LOG TO SYSTEM LOG
gs.info(body);

// (Optional) Send email
var mail = new GlideEmailOutbound();
mail.setSubject(" Approver & Group Membership Audit");
mail.setBody(body);
mail.setFrom("no-reply@yourcompany.com");
mail.setTo("itops@yourcompany.com"); // replace with your team distro
mail.send();

})();

 

Output

  • The script logs everything to the System Log

  • It also sends an email (optional) with the results