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.

View solution in original post

Yeah, this was a great piece to get my feet wet with ServiceNow scripting.  And it's bee years since I've messed around with Javascript; so good on that front too.  I had to add a few more things that I Iearned as I was trying to learn your code:  Using the setWorkflow() function and having ServiceNow return no rows for invalid queries.  And added a few metrics for logging purposes.  But it worked like a charm!  Thanks again, Kilo!