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

Hi Chuck,



  1. If you add a user to HR Parent, they get added to all three HR child groups.   As of now the script is only adding to the first child group it finds and the user is not added to the rest of the child groups.

Thanks for the clarification. I'm on it... stay tuned.


Hi Billi,



As I was looking at this closer, I noticed your addEncodedQuery() line is using current.group. The parent field is stored in 'current.parent'. That might be the source of your issue (if the rest of the assumptions are correct.)


Hi Chuck,



Actually, I think she is correct in using 'current.parent' in her query string.   She is referring to the group element of the current m2m record in [sys_user_group] for the top-level group membership being added... to find the group's children, checking where ('...parent=' + current.group) seems appropriate.



@Billi.... to clarify your situation, is your situation as Chuck gave the example for earlier?   i.e., are there multiple sibilings at the same level and it is only updating the first?   Or is it a hierarchy issue, where there are children/grandchildren/etc., e.g.:



        HR Parent


          +-HR Child1


                    +-HR Child2


          +-HR Child3





Thanks,


-Brian


randrews
Tera Guru

ok the first thing i would do is toss in some add info messages to see what is going on.. i think you are VERY close...




so on line 11 i would add gs.addInfoMsg('found a parent');   //check the sytax on the addinfo message



then between 18 and 19 i would add   gs.addInfoMsg(attempting to insert record);



assuming those work and i suspect they will.. the next thing i would do is toreplace this line



  mem.group = grp.group;  


with



mem.group = grp.group.toString();



i am betting you are getting a pointer instead of the value.