How to sync Parent group members to Child groups

billi_lumley
ServiceNow Employee
ServiceNow Employee

Hello!   Looking for a business rule or SI to sync parent group members to child groups when a new members is added to a parent group.   I had created a business rule on the group member table; however I'm not having any luck.

//check if group is a Parent

var grp = new GlideRecord("sys_user_group");

grp.addQuery("parent", current.group);

grp.addQuery('type', 'CONTAINS', '7e741272efe2010047920fa3f8225643'); //human_resources

grp.addQuery('active', true);

grp.query();

//if group exists as parent, assign new user to the child groups

while (grp.next()) {

  var mem = new GlideRecord("sys_user_grmember");

  mem.addQuery("user", current.user);

  mem.addQuery("group", grp.group);

  mem.query();

  //This is checking to see if group record already exists? - What if they were added to the group prior to this rule being instituted?

  if (!mem.next()) {

  mem.user = current.user;

  mem.group = grp.group;

  mem.insert();

  }

}

1 ACCEPTED SOLUTION

Chuck Tomasi
Tera Patron

Here you go Billi. No charge for the PS time. 🙂 Comments at the top indicate how to set up the business rule. This thing adds AND deletes members from the child tables. 🙂 Don't forget to dump this stuff inside the existing wrapper function that comes with default AFTER business rules.

 

// Table sys_user_grmember
// Insert: true
// Update: true
// When: After
// Condition current.group.getDisplayValue() == 'HR Parent'

//find active child groups
var childArr = [];
var thisUser = current.getValue('user');
var grp = new GlideRecord('sys_user_group'); grp.addEncodedQuery('active=true^parent=' + current.getValue('group')); grp.query(); gs.print('count=' + grp.getRowCount()); while (grp.next()) { childArr.push(grp.getValue('sys_id')); gs.print(grp.getDisplayValue()); } // Add user to the child groups if (current.operation() == 'insert') { gs.print('INSERT'); for (var i = 0; i < childArr.length; i++) { if (userInGroup(thisUser, childArr[i])) { gs.print('user is already in the group ' + childArr[i]); continue; } addUserToGroup(thisUser, childArr[i]); } } // Remove user from child groups if (current.operation() == 'delete') { gs.print('DELETE'); for (var i = 0; i < childArr.length; i++) { if (!userInGroup(thisUser, childArr[i])) { gs.print('user is NOT in the group ' + childArr[i]); continue; } deleteUserFromGroup(thisUser, childArr[i]); } } function userInGroup(user, group) { var ug = new GlideRecord('sys_user_grmember'); var q = 'user=' + user + '^group=' + group; // user=46d44a23a9fe19810012d100cca80666^group=dc8d86c213d31200ae44b4622244b03d // HR Child1 (want to see) // user=46d44a23a9fe19810012d100cca80666^group=a49d86c213d31200ae44b4622244b0e9 // Got (3) ug.addEncodedQuery(q); ug.query(); gs.print('userInGroup(): q=' + q + ' count=' + ug.getRowCount()); return ug.hasNext(); } function deleteUserFromGroup(user, group) { if (!user) return; if (!group) return; var ug = new GlideRecord('sys_user_grmember'); var q = 'user=' + user + '^group=' + group; // user=46d44a23a9fe19810012d100cca80666^group=dc8d86c213d31200ae44b4622244b03d // HR Child1 (want to see) // user=46d44a23a9fe19810012d100cca80666^group=a49d86c213d31200ae44b4622244b0e9 // Got (3) ug.addEncodedQuery(q); ug.query(); gs.print('deleteUserFromGroup(): q=' + q + ' count=' + ug.getRowCount()); if (ug.next()) { gs.print('delete'); ug.deleteRecord(); } } function addUserToGroup(user, group) { if (!user) return; if (!group) return; var ug = new GlideRecord('sys_user_grmember'); ug.newRecord(); ug.user = user; ug.group = group; ug.insert(); gs.print('insert'); }

 

View solution in original post

16 REPLIES 16

Chuck Tomasi
Tera Patron

Hi Billi,



Quick question. what's the use case for having a parent group and child groups if they all have the same members?


acirovic1
Giga Expert

The whole point of having the parent/child groups is not to have to do something like this.


Thank you, as I am well aware of that.   The request is around managing a small set of HR-related groups; customer would like to ensure that when adding a member to 1 of 3 parent groups...that user is added to the HR child groups as they are separate by regions.   The parent groups are used to control security around multiple areas of the HRSM application.   So without further explanation...I'm looking for a BR to accomplish that.     I have a BR in place, however it is only updating the first child group it finds.



//find child groups


var childArr = [];


var grp = new GlideRecord('sys_user_group');


grp.addEncodedQuery('active=true^parent=' + current.group);


grp.query();


while(grp.next()){


  childArr.push(grp.sys_id.toString());


}


//add member to those groups


for(i=0;i<childArr.length; i++){


  var grMem = new GlideRecord('sys_user_grmember');


  grMem.addQuery('group', childArr[i]);


  grMem.addQuery('user', current.user);


  grMem.query();


  if(!grMem.next()){


  grMem.initialize();


  grMem.user = current.user;


  grMem.group = childArr[i];


  grMem.insert();


  }


}


Just so I'm clear on this... Which of the following scenarios are we talking about given this use case:



HR Parent


+-HR Child1


+-HR Child2


+-HR Child3



  1. If you add a user to HR Child1, they get added to HR Parent automatically (if they don't already exist)
  2. If you add a user to HR Parent, they get added to all three HR child groups
  3. If you add a user to HR Child1, they get added to HR Parent and the other HR child groups