Best Way to Dynamically Create a Group when it Doesn't Exist

Brizky
Giga Expert

Hey, folks,

 

I'm in the process of learning ServiceNow while also developing for it.  I have a task that I can't seem to figure out how to approach.

 

I want to go through my collection of users, check their department (if specified) and add them to a group with the same name as that department.  But I also want to check to see if said department exists first.  And if not, create it before adding the user as a member of it.

Being a novice I thought I'd be able to do it via a Workflow.  Got to a certain point and felt that that wasn't the way to do it.  Then I started looking into scripting, which then led me to GlideRecord and after reading through that and trying to figure out where to create the script, I felt that that wasn't the right spot either.

So I'm not sure in what direction I should be heading to do this.  And I'm not experienced enough to know if these approaches are even viable or not.

So just looking for some input that can put me in the right direction.

Thanks,

B.

1 ACCEPTED SOLUTION

You can run it in the Scripts - Background module. As provided, it will only show what it will do.  Once you are comfortable with that, set 'dryRun' to false and run.  Save the output for a record of what was done.  And there will be a "Rollback" option to reverse the changes if desired.

 

Also, if this is a policy you want, then the logic inside the while loop can be used in a Business rule for the sys_user table, so that new records in sys_user will be processed like the script does.  But then when adding a new Department, you can also then create a Group to match, and then when adding a new user, you can manually assign the user to that group.  If a user changes Departments, then you will want to remove the old Group membership and add a new one.

 

I'll be happy to answer any questions.

View solution in original post

5 REPLIES 5

Bert_c1
Kilo Patron

Hi,

 

A script can be used to do that, you would run that in the "Scripts - Background" module.  And you would need to use the GlideRecord APIs

 

https://docs.servicenow.com/bundle/utah-api-reference/page/app-store/dev_portal/API_reference/GlideR...

 

There is the department field on the sys_user table, it is a reference to the 'cmn_department' table. you would query that table using "cmn_departmentRecordObject.addQuery('sys_id', userRecordObject.sys_id.toString());"

 

A start:

 

 

var dryRun = true;                        // don't change until we've tested the query
var sugr = new GlideRecord('sys_user');
sugr.addNotNullQuery('department');
sugr.query();
while (sugr.next()) {
	gs.info("Found user: " + sugr.user_name + " with department = " + sugr.department.getDisplayValue());
	dept = new GlideRecord('cmn_department');
	dept.addQuery('sys_id', sugr.department);
	dept.query();
	if (dept.next()) {
		gs.info("Found department: " + dept.name);
		// check for group with same name, if it doesnt' exist, create one
		var needGroup = 0;
		var newGroup = '';
		var grp = new GlideRecord('sys_user_group');
		grp.addQuery('name', dept.name);
		grp.query();
		if (grp.next()) {
			// A group exists
		}
		else {
			// create new group
			gs.info("Did not find group with name = " + dept.name + " it will be created.")
			grp.initialize();
			grp.name = dept.name;
			needGroup = 1;                    // creating a new group
			if (!dryRun) {
				newGroup = grp.insert();
			}
			// Now add current user to the group
			gs.info("Adding user " + sugr.user_name + " to the new group: " + grp.name + ".");
			var grpmem = new GlideRecord('sys_user_grmember');
			grpmem.initialize();
			grpmem.user = sugr.sys_id;
			grpmem.group = newGroup;
			if (!dryRun) {
				grpmem.insert();
			}
		}
	}
	
}

 

See if that meets your needs, and when ready, set 'dryRun' to false.

 

Use similar logic in a Business Rule if when sys_user_records are created, you want the same behavior.

Bert_c1
Kilo Patron

Hi @Brizky ,

 

Here is an updated script, as the above has a flaw that only the first user in a particular 'Department' will be added to the corresponding group.  the following corrects that.

 

// Script to create group based on user department name, if not group exists.
// And then checkto see if the user to that group, add the user to the group if
// not a member 
var dryRun = true;                        // don't change until we've tested the query
var sugr = new GlideRecord('sys_user');
sugr.addNotNullQuery('department');
sugr.query();
while (sugr.next()) {
//	gs.info("Found user: " + sugr.user_name + " with department = " + sugr.department.getDisplayValue());
	dept = new GlideRecord('cmn_department');
	dept.addQuery('sys_id', sugr.department);
	dept.query();
	if (dept.next()) {
//		gs.info("Found department: " + dept.name);
		// check for group with same name, if it doesnt' exist, create one
		var groupID = '';
		var grp = new GlideRecord('sys_user_group');
		grp.addQuery('name', dept.name);
		grp.query();
		if (grp.next()) {
			// A group exists
			groupID = grp.sys_id.toString();
		}
		else {
			// create new group
			gs.info("Did not find group with name = " + dept.name + " it will be created.")
			grp.initialize();
			grp.name = dept.name;
			if (!dryRun) {
				groupID = grp.insert();
			}
		}
		// Now check if current user is in the group
		var grpmem = new GlideRecord('sys_user_grmember');
		grpmem.addQuery('user', sugr.sys_id);
		grpmem.addQuery('group', groupID);
		grpmem.query();
		if (grpmem.getRowCount() == 0) {
			gs.info("Adding user " + sugr.user_name + " to the new group: " + grp.name + ".");
			grpmem.initialize();
			grpmem.user = sugr.sys_id;
			grpmem.group = groupID;
			if (!dryRun) {
				grpmem.insert();
			}
		}
	}
	
}

Brizky
Giga Expert

Oh wow!  I appreciate it!  Going to print out and learn up on it to make sure I understand it all and then will test.  Thank you!  Digging in right now!

You can run it in the Scripts - Background module. As provided, it will only show what it will do.  Once you are comfortable with that, set 'dryRun' to false and run.  Save the output for a record of what was done.  And there will be a "Rollback" option to reverse the changes if desired.

 

Also, if this is a policy you want, then the logic inside the while loop can be used in a Business rule for the sys_user table, so that new records in sys_user will be processed like the script does.  But then when adding a new Department, you can also then create a Group to match, and then when adding a new user, you can manually assign the user to that group.  If a user changes Departments, then you will want to remove the old Group membership and add a new one.

 

I'll be happy to answer any questions.