sabell2012
Mega Sage

NOTE: MY POSTINGS REFLECT MY OWN VIEWS AND DO NOT NECESSARILY REPRESENT THE VIEWS OF MY EMPLOYER, ACCENTURE.

DIFFICULTY LEVEL:   INTERMEDIATE to ADVANCED

Assumes knowledge and/or familiarity of several different areas in ServiceNow.

____________________________________________________________________________

Recently two of our developers (adam.keller, travisbell) came to me and asked if it were possible using Service Catalog and Workflows to do the following:

  1. Add multiple Users to a Group with a dynamic request for Approval
  2. Add a single User to multiple Groups with a dynamic request for Approval
  3. Each Group Approval Request/Response must not hold up the other Group Approvals.
  4. The Group Manager would be the approver for each group.

I thought the answer would be an easy one.   Boy, was I wrong!

What I attempted:

  1. My first thought was to simply use the Approval - Users Activity, and feed it a dynamic group for approval.   However, even though it would normally work for requesting group approvals it would not work to fulfill the third and fourth requirements.
  2. I next tried to construct a workflow loop using the Approval - Users Activity.   Essentially take all of the users and present them as a whole to each group for approval.   This worked fine, but that pesky third requirement got in the way again.
  3. Next I decided to try kicking off multiple workflows from a calling workflow.   This almost worked.   It behaved VERY strangely.   For example, with two groups to be approved one would wait for approval like it was supposed to, but the other one would auto-approve!   Probably a timing issue.   I will have to dig deeper on this and see if I can find out why.
  4. I then decided to try the same thing with Events.   So created a custom event, complete with Script Action to be called from the workflow.   Essentially this is the same as just calling a workflow.   Sure enough same behavior as my second scenario!   First one waited for approval, the second group auto-approved!   Yeah, gotta be timing...
  5. The parallel RITM approach just HAD to be the solution here, but how to do that?   I broached the subject with b-rad (Brad Tilton), and he pointed me to a response to a similar problem stated on the Community.   duffyb (Barbara Duffy) (response link) had run into how to properly create a RITM in code.   He said he had used her solution, and it had worked for him.   The RITM would then call it's requisite workflow and the approvals would work correctly.   Tried it, and it failed! This time the groups and users values were not making it from the calling workflow to the new RITMs!   It was creating the RITMs fine, but the values weren't showing up.
  6. In the wind-down at a meeting, Brad and I were discussing the issue, and mamann (Mark Amann) who was present said he would like to know more as it sounded familiar.   Sure enough Mark had also solved something very similar to this.   Same kind of thing where a RITM was being created in code, but the variables passed into the workflow did not populate.   He had the final bits of the puzzle:   You have to throw a timer in the RITM workflow to wait until the passed-in variables actually arrive!   Actually arrive?   Looks like there is a timing thing going on after all!   Sure enough when I put that last bit of magic into the code it worked!


Who says networking doesn't get results?!   🙂


So I decided to share.   It is obvious that this problem is recurring, and not too many people were aware of the solution.   I certainly wasn't!


Prerequisites

  1. Some knowledge of creating Workflows with the Workflow Editor
  2. Some knowledge of creating Service Catalog Items
  3. Some knowledge of creating and scripting Workflow activities



Lab 1.1: Create the Add Users to Groups Workflow

1. Navigate to Workflows -> Workflow Editor.   The Workflow Editor will be displayed.

2. Click on the "+" button to create a new workflow.

a. Name: Add Users to Groups

b. Table: Catalog Item [sc_cat_item]

c. If condition matches:   Run the workflow

d. Click on the Submit button to create the workflow.

3. Navigate in the workflow to Core -> Utilities and place a Run Script Activity between the Begin and End activities.

a. Name: Initilialize

b. Script:



// interestingly because of the timing issues I had to use

// a hardcoded context value with my identifier

var identifier = 'Add Users To Groups.' + activity.name;

var message = '--->\n';

// From the initial RITM

var groups = current.variables.groups + '';

var users = current.variables.users + '';

var groupList = [];

// if we have more than one they will be comma delimited

if (groups.indexOf(',') > -1) {

  groupList = groups.split(',');

}

else {

  groupList.push(groups);   // only one group

}

// just a few debug messages - remove these when going to QA

message += 'groups: ' + groups + '\n';

message += 'groupList: ' + groupList.length + '\n';

message += 'users: ' + users + '\n';

message += 'current.request: ' + current.request;

// get the sys_id of the RITM to create. In this case we

// want to create a new RITM for each group that we want

// to request access from

var requestItemTemplate = new GlideRecord('sc_cat_item');

requestItemTemplate.get('name', 'Add Users to Group');

var ritmTemplateID = requestItemTemplate.sys_id + '';

// loop through and create a new RITM for each group,

// attached to the parent RITM

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

  var group = groupList[i] + '';

 

  // undocumented feature - no API definition unfortunately

  // appears to do the following:

  // - Create new RITM based on template

  // - Copy all variables from the template to the new RITM

  // - Associate the new RITM to the current RITM

  // - Trigger the workflow (state = 2)

  var requestHelper = new GlideappCalculationHelper();

  requestHelper.addItemToExistingRequest(current.request + '', ritmTemplateID + '', 1);

  // Not sure of the function or necessity of this, but it is

  // always present with the 2-3 examples I found

  requestHelper.rebalanceRequest(current.request + '');

 

  // Find our new RITM (it will be the most recent right?)

var reqItem = new GlideRecord('sc_req_item');

  reqItem.addQuery('request', current.request + '');

  reqItem.addQuery('cat_item', ritmTemplateID + '');

  reqItem.orderByDesc('number');

  reqItem.setLimit(1);

  reqItem.query();

 

message += '---> TOTAL: ' + reqItem.getRowCount() + '\n';

  // Now set the variable values of our new RITM to the targeted

  // group for approval, and the users we want added. Even after

  // this update is done it takes a bit for the new RITM workflow

  // to wake up to these new values

if (reqItem.next()) {

    message += '---> Updating: ' + reqItem.sys_id + '\n';

    reqItem.variables.group = group + '';

    reqItem.variables.users = users + '';

    reqItem.parent = current.sys_id + '';

    reqItem.update();

  }

}

// debug - write out all of our results to the system log

gs.log(message, identifier);

c. Click the Submit button to save your activity.



Lab 1.2: Create the Add Users to Group Workflow

1. From the Workflow Editor click on the "+" button to create a new workflow.

a. Name: Add Users to Group

b. Table: Catalog Item [sc_cat_item]

c. If condition matches:   Run the workflow

d. Click on the Submit button to create the workflow.

2. Navigate in the Workflow Editor to Core -> Timers and place a Timer Activity after the Begin.

a. Name: Wait for Vars

b. Timer based on: A user specified duration.

c. Duration: 15 seconds.

d. Click on the Submit button to create the Timer.

3. Navigate to Core -> Conditions and place an If Activity after the Timer Activity.

a. Name: Are Vars Filled In?

b. Advanced: Checked

c. Script:

answer = ifScript();

function ifScript() {

  if (JSUtil.notNil(current.variables.group) && JSUtil.notNil(current.variables.users)) {

    return 'yes';

  }

  return 'no';

}

d. Click on the Submit button to create the If Activity.

4. Navigate to Core -> Utilities and place a Run Script Activity between the Begin and End activities.

a. Name: Initilialize

b. Script:

var identifier = context.name + '.' + activity.name;

var users = current.variables.users + '';

var group = current.variables.group + '';

var messages = '--->\n';

// debug - edit out for production

messages += '---> current.variables.users: ' + current.variables.users + '-' + identifier + '\n';

messages += '---> current.variables.group: ' + current.variables.group + '-' + identifier + '\n';

var userList = [];

if (users.indexOf(',') > -1) {

  userList = users.split(',');

}

else {

  userList.push(users + ''); // only one user found

}

// retrieve the list of user names

var userRecords = new GlideRecord('sys_user');

userRecords.addQuery('sys_id','IN',userList);

userRecords.query();

var userNames = [];

while(userRecords.next()) {

  userNames.push(userRecords.name + '');

}

// retrieve all the users already present in the group

var groupMembers = new GlideRecord('sys_user_grmember');

groupMembers.addQuery('group', group);

groupMembers.query();

// remove already existing members from the list

while(groupMembers.next()) {

  var member = groupMembers.user + '';

  if (userList.indexOf(member) > -1) {

  messages += '---> Member removed: ' + member + '\n';

  userList.splice(userList.indexOf(member),1); // remove the already existing member

  }

}

// retrieve group manager, and group name

var groupInfo = new GlideRecord('sys_user_group');

if (groupInfo.get('sys_id', group)) {

  workflow.scratchpad.manager = groupInfo.manager + '';

  workflow.scratchpad.groupName = groupInfo.name + '';

  messages += '---> workflow.scratchpad.groupName: ' + workflow.scratchpad.groupName + '-' + identifier + '\n';

  messages += '---> workflow.scratchpad.manager: ' + workflow.scratchpad.manager + '-' + identifier + '\n';

}

workflow.scratchpad.userNames = userNames;

workflow.scratchpad.group = group;

workflow.scratchpad.users = userList;

workflow.scratchpad.messages = messages;

c. Click the Submit button to save your activity.



5. Navigate to Core -> Conditions and place an If Activity after the Initialize Run Script Activity.

a. Name: Any users to process?

b. Advanced: Checked

c. Script:

answer = ifScript();

function ifScript() {

  if (workflow.scratchpad.users.length > 0) {

    return 'yes';

  }

  return 'no';

}

d. Click the Submit button to save your activity.



6. Place another If Activity after the Any Users to Process If Activity.

a. Name: Is Manager Present?

b. Advanced: Checked

c. Script:

answer = ifScript();

function ifScript() {

  if (JSUtil.notNil(workflow.scratchpad.manager)) {

  return 'yes';

  }

  return 'no';

}

7. Navigate to Core -> Approvals and place an Approval - User Activity after the If Activity.

  So here is our dynamic approval.   Simple, huh?   🙂   Remember requirement #4.   We only want to request approval from the group manager.

a. Name: Get Group Manager Approval

b. Advanced: Checked

c. Script:

var identifier = context.name + '.' + activity.name;

workflow.scratchpad.messages += '---> approval group: ' + workflow.scratchpad.group + '-' + identifier + '\n';

answer = [];

answer.push(workflow.scratchpad.manager);

d. Click the Submit button to save your activity.



8. Navigate to Core -> Utilities and pull out five Run Script Activities.

a. First activity:

i. Name: Log Users Already Exist

ii. Script:

workflow.scratchpad.messages += '---> Group (' + workflow.scratchpad.groupName + '): All users already exist in the group, or no users to process!   Process ending.\n';

iii. Click the Submit button to save your activity.

b. Second activity:

i. Name: Log Manager Not Present

ii. Script:

workflow.scratchpad.messages += '---> Group (' + workflow.scratchpad.groupName + '): The Group Manager was not found. The manager must be present! Process ending.\n';

iii. Click the Submit button to save your activity.

c. Third activity:

i. Name: Log Request Rejected

ii. Script:

workflow.scratchpad.messages += 'Users ('+ workflow.scratchpad.userNames +') rejected for group ---> '

  + workflow.scratchpad.groupName + '\n';

iii. Click the Submit button to save your activity.

d. Fourth activity:

i. Name: Add Users to Group

ii. Script:

addUsersToGroup(workflow.scratchpad.users, workflow.scratchpad.group);

function addUsersToGroup(userIDList, groupID) {

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

  workflow.scratchpad.messages += '\tUser (' + userIDList[i] + ') added to group: '

  + workflow.scratchpad.group + '\n';

  var groupMember = new GlideRecord("sys_user_grmember");

  groupMember.initialize();

  groupMember.user = userIDList[i] + '';

  groupMember.group = groupID + '';

  groupMember.insert();

  }

}

iii. Click the Submit button to save your activity.

e. Fifth activity:

i. Name: Log Messages

ii. Script:

var identifier = context.name + '.' + activity.name;

gs.log(workflow.scratchpad.messages, identifier);

iii. Click the Submit button to save your activity.


9. Navigate to Core -> Approvals and pull out an Approval Action Activity.

a. Name: Auto-Reject

b. Action: Mark task rejected.

10. Wire everything up to look like the following diagram:

find_real_file.png

NOTE:   The combination of the If and Timer activities make the workflow wait until the If condition is met.   In this case the variables are filled in.

11. Publish your workflow.   In Helsinki I found that sometimes my new changes were not picked up by Service Catalog unless I did this!   So if you find that modifications you made do not seem to appear during testing then this is the solution.



Lab 1.3: Create the Service Catalog Interface

1. Navigate to   Service Catalog -> Maintain Categories and create a new Category.

a. Title: User and Group Exercises

b. Catalog: Service Catalog

c. Right-click on the header and save your new category.

2. Add a new Catalog Item

                  NOTE: If you do not see some of the following fields on your form you may have to add them to your form.

a. Name: Add Users to Groups

b. Workflow: Add Users To Groups

c. Short description: Add a user to several groups

d. Use cart layout: unchecked

e. Omit price in cart: checked

f. No quantity: checked

g. No proceed to checkout: checked

h. No cart: checked.

i. Right-click on the header and save your new catalog item.

3. Add two variables to the new Catalog Item

a. Variable one

i. Type: List Collector

ii. Question: User(s)

iii. Name: users

iv. Mandatory: true

v. List table: User [sys_user]

vi. Reference Qualifier: active=true

vii. Order: 100

viii. Click on the Submit button to save your variable.

b. Variable two

i. Type: List Collector

ii. Question: Group(s)

iii. Name: groups

iv. Mandatory: true

v. List Table: Group [sys_user_group]

vi. Reference Qualifier: active=true

vii. Order: 200

viii. Click on the Submit button to save your variable.

Your Catalog Item should look something like this:

4. Add another new Catalog Item

a. Name: Add Users to Group

b. Workflow: Add Users To Group

c. Short description: Add users to group

d. Use cart layout: unchecked

e. Omit price in cart: checked

f. No quantity: checked

g. No proceed to checkout: checked

h. No cart: checked.

i. Right-click on the header and save your new catalog item.

5. Add two variables to the new Catalog Item

a. Variable one

i. Type: Reference

ii. Question: Group

iii. Name: group

iv. Mandatory: true

v. List table: Group [sys_user_group]

vi. Reference Qualifier: Simple

vii. Order: 100

viii. Click on the Submit button to save your variable.

b. Variable two

i. Type: List Collector

ii. Question: Users to add to group

iii. Name: users

iv. Mandatory: true

v. List Table: User [sys_user]

vi. Reference Qualifier: active=true

vii. Order: 200

viii. Click on the Submit button to save your variable.

Your Catalog Item should look something like this:

find_real_file.png

Lab 1.4: Testing

1. First we need to activate our new Category.   Navigate to Self-Service -> Service Catalog.

2. Click on the "+" button in the upper right corner to open the Sections form.

3. Add User and Group Exercises someplace on the form.

4. Click the "x" button to close the Sections form.

5. Now we can test our new Catalog Item.   Click on the User and Group Exercises link.

6. Click on the Add Users to Groups link.

Your Service Catalog Item form should look a bit like this:

7. Pick your favorite group, and a couple of users to add, and click the Order Now button.   The Order Status form will be displayed.  



8. Click on the first request number created (in my case REQ0010081).   The Request form will be displayed.  

9. Scroll to the bottom of the request form and note that there are three RITMs.   The first RITM is the main workflow (kicked off by this request), and the other two were generated by that workflow.

10. In the related list order the RITMs by Number ascending and click on the first (lowest numbered) record.   For me it would be RITM0010099.

11. Scroll to the Related Links and click on the Show Workflow link.   This will display the workflow context diagram.   It should look something like this:

12. Close this browser tab, and return to the Request Item tab.

13. Back arrow on your browser to get back to the Request form, scroll to the related links, and pick the second RITM record.

14. Scroll to the bottom of the RITM form.   You should see one or more approvers (depending on how many were already present in your group).

15. In related links for the RITM click on the Show Workflow link.   It should look something like this:

find_real_file.png

NOTE: By definition if there is no one already present in the group it will auto-approve.   So you may want to add at least one user to your group before you run this test.

16. Close this browser tab, and return to the Request Item tab.

17. From the Approvers tab, go ahead and approve one of the approvers.   You should see a couple of roles added messages appear at the top of the form.

18. Back arrow on your browser to get back to the Request form, scroll to the related links, and pick the second RITM record.   Look at the workflow (it should be the same as the other).   Approve this RITM as well.

19. Now look at that RITMs workflow again.   You will observe the completion of the flow.

find_real_file.png

20. Finally navigate to User Administration -> Groups, and open your group.   You should see all the newly added users in the Group Members tab.

Obviously, other tests you will want to perform are:

1. Do all users exist in the group?

2. Is the manager field filled in on the group?

3. Manager rejects the request

And you are done!

You will probably want to go the extra step of notifying the requestor of the results of each request, and you could also set up the status for the user to track where their request currently is.   Just a couple of cleanup items.   🙂

I want to highly recommend taking the ServiceNow Scripting training class should you get the opportunity.   The class has an entire module covering Workflow Scripting!

Steven Bell

accenture logo small.jpg

For a list of all of my articles:   Community Code Snippets: Articles List to Date

Please Share, Like, Bookmark, Mark Helpful, or Comment this blog if you've found it helpful or insightful.

Also, if you are not already, I would like to encourage you to become a member of our blog!

Comments
ServiceNow Employee
ServiceNow Employee

Hi sabell2012,



I think there is something wrong with the instructions or I'm just not understanding it. Lab 1.1. doesn't do much. Then Lab 1.2 starts the same way that Lab. 1.2 did and a bit down the same Initialize scripts comes along again.



I really appreciate you Mini-Labs, What I'm wonder if it's possible if you can explain why do to the different steps in the workflow. For example why do you start with a wait timer?



//Göran


Mega Sage
Mega Sage

Göran:



Thanks!



Lab 1.1 is a "setup" lab.   It executes the looping structure that will make all of the simultaneous workflow calls necessary to do the individual access approval requests.



Lab 1.2 is actually the core workflow.   It does all the work for each dynamic access approval request.



Not that the first Lab has you create the Add Users to Groups workflow (note the plural nature of the Groups).



The second has you create the Add Users to Group workflow (Group singular)



Perhaps this diagram will clear up the the confusion on what is happening with the calling structure.



The Second set of workflows have to wait on the Vars to appear as they are transmitted down from the calling workflow (Groups).   The second set of RITMs don't receive their respective variables (and data) from the calling workflow right away. This appears to be a lag issue with all the messaging going on.   So it required a timer and If Activity check to wait on continuing execution until those variables with data arrived.



Hope that helps,



Steven.



Please Share, Like, Bookmark, Mark Helpful, or Comment this blog if you've found it helpful or insightful.



find_real_file.png


ServiceNow Employee
ServiceNow Employee

Ahh Thanks Steven,



I don't know how many times I was staring at the names and I didn't see the difference with the 's' 😎 That clears up a few questions 😃 Hoping do dig through the rest of the Lab tomorrow and see the magic happen.



Just this case has been something on me mind quite some time, checking off some of my own administrative stuff on the "manual goes automagic" list.



//Göran


ServiceNow Employee
ServiceNow Employee

Hmm.. Think I need some more help here sabell2012



Trying to get it to work, but not working as I thought it should. The workflow from 1.1. never gets created. I'm wondering if the problem is that on Lab 1.3 and 2b, shouldn't it be workflow "add users to groups" instead of "add users to group"?



I did for example an example of two users that are going into 2 groups. this generated one ritm and that workflow isn't going past the waiting for vars. but that is probably because the other workflow doesn't set them with it's script activity? and I guess there should be one ritm for each group as well?



But if I change the workflow on the item, it freaks out and creates like 47 RITM's after I press "order now" with 2 users and 2 groups.


Know where I might start to look for errors?




//Göran


Giga Guru

I'm not sure if this is related, but I was wondering if the workflows actually need to be built on the "Requested Item [sc_req_item]" table (rather than the "Catalog Item [sc_cat_item]" table). I've always built on Requested Item because building on Catalog Item would seem to mean that the workflow "runs on" the back-end record (and not each individual RITM ticket).



FULL DISCLOSURE: I have not tried this solution, myself, but it looks awesome, so I've definitely bookmarked the page!


Mega Sage
Mega Sage

So I have had some people report back to me on this, and there are a couple of defects, AND a couple of missing steps.   I have updated the Lab and fixed everything that was found so far.   Sorry about the confusion.   I proof read my own stuff this time and missed some things!   Ugh.   Bad day.



1. Lab 1.2.   Step 4.   Script.   sys_users is incorrect.   This should by sys_user


2. Lab 1.3.   Step 2.   Workflow.   This should be: Add Users to Groups


3. Lab 1.3.   Missing steps!   These should be the following:



4. Add another new Catalog Item



a. Name: Add Users to Group


b. Workflow: Add Users To Group


c. Short description: Add users to group


d. Use cart layout: unchecked


e. Omit price in cart: checked


f. No quantity: checked


g. No proceed to checkout: checked


h. No cart: checked.


i. Right-click on the header and save your new catalog item.



5. Add two variables to the new Catalog Item



a. Variable one



i. Type: Reference


ii. Question: Group


iii. Name: group


iv. Mandatory: true


v. List table: Group [sys_user_group]


vi. Reference Qualifier: Simple


vii. Order: 100


viii. Click on the Submit button to save your variable.



b. Variable two



i. Type: List Collector


ii. Question: Users to add to group


iii. Name: users


iv. Mandatory: true


v. List Table: User [sys_user]


vi. Reference Qualifier: active=true


vii. Order: 200


viii. Click on the Submit button to save your variable.


Mega Sage
Mega Sage

Göran:



I had some feed back from a couple of others, and found there are a couple of problems (now corrected).   See my most recent note on this thread for the Errata and fixes.   Sorry for the confusion.   This was a bit more of a complex lab, and thought I had reviewed it all thoroughly.   Guess not.  



Steven.


Mega Sage
Mega Sage

Yeah, this is one of those "special" cases where what you would think work didn't (see my list of "what I tried").   These RITMs are actually created and associated to the SC on-the-fly.


Mega Guru

Hi Steven,



Thanks for submitting this post, it is very helpful. It seems very simple with Add Remove Users to Group but is not; and this post explains exactly why.



Could you please help clarify the below points:


1. Lab 1.1 is creating a REQ and has an RITM. This RITM is responsible for creating multiple RITMs (Lab 1.2). So, there is only one REQ which contains all the RITMs?


2. The first RITM created in Lab 1.1 is defunct and not worked upon. It is just a placeholder to create multiple RITMs?



Regards,
Kuldeep


Kilo Contributor

hi sir am very happy talking with u it is great opportunity to me   in the above scenario was super in similar way   i would like to create a one requirement i.e from the ci slush bucket i would like to select a 10 items then there must be create a 10 task and it would go for approval for 10 assigned groups is it possible sir can u   pls help me      


Tera Expert

Dear sir,



                I am following your lab and would like to know if there is any difference doing the same using the ServiceNow Istanbul version. As I have, this version deployed here ServiceNow . I am aware that it's been almost a year from when the date you published, but I still am interested in working on it. Kindly request you to let me know if there are any changes required for the latest Istanbul version which has been released on ServiceNow.


Kilo Explorer

Thanks Steve,


it is a great article and it is very much helpful . but I don't understand how you are pulling the user records based on sys_id. is sys_id contains userlist


var userRecords = new GlideRecord('sys_user');  


userRecords.addQuery('sys_id','IN',userList);  


userRecords.query();  


Thanks


Kilo Explorer

Great article. Worked like a charm. Is there something similar for removing users from groups as well. I have zero ServiceNow coding/scripting experience, but I want to make a business case to the relevant people that automation of adding / removing users should be a fairly simple task and we should go ahead and implement it in our environment.


Mega Guru

Was anyone successful in finding a lab like this step by step guide to remove users from groups?

Tera Contributor

@sabell2012, 

Thanks for the share, I found this to be very helpful. Now I will work on the ability to remove users as well. 

 

 

 
Tera Guru

Steven,

I keep trying to get this to work, but it always errors out on the "Are Vars Filled In?" activity. I'm on Madrid, using a clean dev instance. I can't determine why this errors out like this. Any advice you can offer?

find_real_file.png

Thanks,

 

Robbie

Community Alums

Hi Sir,

 

Its very helpful to do my requirement,

Now my point is how can we close all RITM and based on that Request, Through BR or workflow only, Kindly guide me.

 

Thanks

Tera Expert

Hello,

i use Madrid instance.

the workflows not appear in the list when i want to set it in the catalog item,

and if i put it manually then can't be save because of invalid reference...

If i modify the workflow from catalog item to requested item, than the workflow can be selectable,

but not work as it expected.

Can anybody help what am i do wrong? 🙂

thanks,

Jozsef

Mega Explorer

Hi Steve,

I have tried this today and unable to attach the worklflow as they are built on sc_cat_item rather than sc_req_item. Can you please help.

Thanks!!

Snowslack

Kilo Explorer

Hi...

I'm working in Madrid, and with some minor variable(s) and workflow activity modifications, I was able to use your solution successfully.  Thanks so much for sharing your knowledge.

My initial requirement was to allow one (1) user request access to multiple groups and generate an RITM for approval from each requested group's manager.  

Again, with some minor variable and WF activity mods, your solution handles this functionality perfectly.

I now have an additional requirement to "loop through the requested groups to verify if the user already exist and if so do not generate an RITM.

Please advise/share any additional scripts to implement this functionality to your solution?

Thanks in advance!

Kilo Explorer

This is working great.  Need a bit more help when "Remove" user is opted? Problem I'm running into is, "Remove" acts the same as "Add"... "Add" does check the user and if already member of a group in the array, "No RITM" is generated, but "Remove" generates an RITM regardless...

Here's the code:

/* Get the sys_id of the RITM to create. In this case we want to create a new RITM for each group that we want to request access from */
var requestItemTemplate = new GlideRecord('sc_cat_item');
requestItemTemplate.get('name', 'Add User to Group');
var ritmTemplateID = requestItemTemplate.sys_id + '';

/* Loop through and create a new RITM for each group access is requested and attached to the parent RITM */
for (var i=0; i < groupList.length; i++) {
var group = groupList[i] + '';

/* This is an undocumented feature - no API definition unfortunately appears to do the following:
1. Create new RITM based on template
2. Copy all variables from the template to the new RITM
3. Associate the new RITM to the current RITM
4. Trigger the workflow (state = 2) */

//check membership if the user to each group being looped through
var groupMembers = new GlideRecord('sys_user_grmember');
groupMembers.addQuery('group', group);
groupMembers.addQuery('user', user);
groupMembers.query();
gs.log("Records returned: " + groupMembers.getRowCount());
if (groupMembers.getRowCount() == 0) {
gs.log("User with sys_id: " + user + " is NOT a member of group with sys_id: " + group);
if (add_remove == 'add') {
//open a request to add the user
createItem(ritmTemplateID,current,group);
gs.log("User with sys_id: " + user + " is NOT a member of group with sys_id: " + group + "; Add_remove is: " + current.variables.add_remove + "; Calling to open a new request to add the user");
} else {
//send a notification to the requestor that the user is already a member of the group, no action is taken
gs.log("User with sys_id: " + user + " is currently a member of group with sys_id: " + group + "; Add_remove is: " + current.variables.add_remove + "; Notification to the requestor that the user is already a member of the group and no action is taken");
}
if (add_remove == 'remove') {
//send a notification to the requestor that the user is NOT member of the group and no action is taken
gs.log("User with sys_id: " + user + " is NOT a member of group with sys_id: " + group + "; Add_remove is: " + current.variables.add_remove + "; Notification to the requestor that the user is NOT member of the grou and no action is taken");
} else {
//open a request to remove the user
createItem(ritmTemplateID,current,group);
gs.log("User with sys_id: " + user + " is a member of group with sys_id: " + group + "; Add_remove is: " + current.variables.add_remove + "; Calling to open a new request to remove the user");
}
}
}