Checking if a ServiceNow User is a Member of a Group (Using Sys ID)
- nathanlee142
- Mar 18
- 13 min read
Updated: Apr 1

Verifying user group membership in ServiceNow is crucial for ensuring proper access control and workflow management in your IT processes. By confirming whether a user belongs to a particular group, you can enforce security rules, trigger the right approvals, and automate tasks based on group roles.
For example, you might only allow members of an "IT Administrators" group to access certain forms, or route an incident to a specific team if the requester is part of a designated group. In ServiceNow, groups are often used to manage permissions and assignments, so checking group membership helps maintain governance and compliance in your instance.
Key use cases include:
Access Control: Enforcing ACL rules so that only users in the required group can view or edit sensitive records (e.g. certain HR cases or security incidents).
Workflow Management: Branching logic in approval workflows or task assignments based on whether a user is in a particular group (e.g. auto-approving requests if the requester is in a managers' group).
Automation: Scripted actions or business rules that run only for users who belong to specific support teams or departments, streamlining processes by leveraging group membership.
In this article, we’ll explore how ServiceNow stores user-group relationships and walk through a step-by-step method to check if a user (by their sys_id) is a member of a given group. We’ll also cover alternative approaches (such as using the ServiceNow REST API and client-side strategies) and discuss common issues and best practices for managing group memberships effectively.
Understanding User-Group Relationships in ServiceNow (sys_user_grmember)
ServiceNow uses a dedicated table called Group Members (sys_user_grmember) to maintain the many-to-many relationship between users and groups. In other words, whenever a user is added to a group or removed from a group, ServiceNow creates or deletes a record in the sys_user_grmember table. This table links a user record (sys_user) to a group record (sys_user_group) by their unique identifiers (sys_ids). Each entry in sys_user_grmember has a reference to a User (the user’s sys_id) and a Group (the group’s sys_id), indicating that "User X is a member of Group Y."
For example, if you wanted to list all groups that a certain user belongs to, you could query the sys_user_grmember table for records where the user field matches that user’s sys_id. This is exactly how ServiceNow determines group membership behind the scenes. In fact, you can use a script to fetch all groups for a user by querying this table. The user field on each Group Members record is the sys_id of a user, and the group field is the sys_id of a group. So, checking membership essentially means looking for a record in this table that matches a given user and group.
Understanding this relationship is important, because it means our verification of group membership will involve this table. Next, we’ll dive into how to use server-side scripting with the GlideRecord API to check if a particular user (identified by sys_id) is a member of a specific group.
Checking Group Membership with GlideRecord (Server-side Script)
One of the most straightforward ways to check group membership in ServiceNow is by using a server-side script with the GlideRecord API. GlideRecord allows you to query ServiceNow tables from scripts (Business Rules, Script Includes, Background Scripts, etc.). In this case, we will query the sys_user_grmember table for a combination of a specific user and a specific group. If a record is found, it means the user is in that group; if not, the user is not a member of that group.
Step-by-Step Guide: Checking if a user is in a group by sys_id using GlideRecord
Identify the User and Group – Obtain the sys_id of the user and the sys_id of the group in question.
For example, say we have a user with sys_id aaaaaaaa1bbbbbbb2ccccccc3ddddddd
and we want to check if they are in the "Network Operations" group which has sys_id 11112222333344445555666677778888.
(In a real scenario, you would get these sys_ids from the record URLs or via a query.)
Initialize a GlideRecord on sys_user_grmember – In a server-side script (such as a Background Script or Script Include), create a GlideRecord instance for the Group Members table:
var gr = new GlideRecord('sys_user_grmember');
This will allow us to build a query on the group membership table (which, as noted, stores the mapping between users and groups).
Add Query Conditions – We want to find a record where the user field matches our target user’s sys_id and the group field matches our target group’s sys_id. We add these conditions to the GlideRecord:
gr.addQuery('user', 'aaaaaaaa1bbbbbbb2ccccccc3ddddddd'); // User sys_id gr.addQuery('group', '11112222333344445555666677778888'); // Group sys_id
Here, replace the long strings with the actual sys_ids. We’re effectively saying, “look for a group membership record for this user in this group.” If you only care about whether the user is in any of several groups, you could add multiple queries or use an encoded query, but for a single group check, two conditions are sufficient.
Execute the Query – Call gr.query(); to run the query on the database.
gr.query();
After this, the GlideRecord gr will contain any matching records (at most one record in this case, because a user can appear only once in the same group).
if (gr.next()) {
gs.print('User IS a member of the group.');
} else {
gs.print('User is NOT a member of the group.');
}
In a background script, gs.print will output to the script log. In a Business Rule or other context, you might take some other action (set a field, prevent an update, etc.) based on the result. The key point is that gr.next() moving to a record indicates the membership exists.
Use the Result in Your Logic – Now you can use this boolean outcome in your server-side logic. For instance, in an Access Control script, you might do something like:
var hasAccess = false;
var grCheck = new GlideRecord('sys_user_grmember'); grCheck.addQuery('user', current.requested_for);
// e.g., check the Requested For user
grCheck.addQuery('group', '11112222333344445555666677778888');
sys_id grCheck.query();
if (grCheck.next()) {
hasAccess = true;
}
answer = hasAccess;
This would set the ACL answer to true only if the Requested For user is in that particular group, otherwise false. (Ensure the script runs in a context with permission to read group membership.)
How it Works: Under the hood, the script is simply looking up the Group Members table for a record linking the given user and group. If found, it confirms the relationship exists. This approach leverages ServiceNow’s server-side API and is efficient for on-the-fly checks in Business Rules, Script Includes, or any server script. It’s important to note that this operation is read-only and safe – it doesn’t modify any data; it just queries the table.
Pro Tip: If you need to check membership for the currently logged-in user in a server script, ServiceNow provides a shortcut method: gs.getUser().isMemberOf(<group>). This returns true/false if the current user is in the specified group, and it accepts either a group name or the group’s sys_id as the parameter. For example, gs.getUser().isMemberOf('Network Operations') or gs.getUser().isMemberOf('11112222333344445555666677778888') will yield a boolean result without you writing a GlideRecord query. However, keep in mind this only works for the session user (e.g., in an impersonation or logged-in context). For arbitrary users (not the session user), you would use the GlideRecord approach described above or impersonate that user in code if necessary.
Now that we’ve covered the core server-side method, let’s look at alternative ways to achieve the same result, which can be useful in different scenarios.
Alternative Methods to Verify Group Membership
Depending on your use case, you might not always use a GlideRecord in a synchronous server script. Here are a few alternative methods to check group membership in ServiceNow:
Using the ServiceNow REST API: If you need to verify group membership from an external system or in a client-side script (and you have access to ServiceNow’s API), you can use the Table API to query the sys_user_grmember table. For example, you can perform a GET request to the following endpoint:
GET https://<your_instance>.service-now.com/api/now/table/sys_user_grmember?sysparm_query=user=<USER_SYS_ID>^group=<GROUP_SYS_ID>&sysparm_display_value=true
This query will return the matching group membership record if it exists (including display values for easier reading, due to sysparm_display_value=true).
You could also query by other fields; for instance, using a username instead of sys_id by dot-walking:
sysparm_query=user.user_name=<username>
In summary, the REST API approach is handy for integration scenarios or when writing client-side code (like in Service Portal) where you can call the API via AJAX. Just remember that you’ll need proper authentication (and API permissions) to call this endpoint.
Client-side (GlideAjax): In client scripts or UI policies, you cannot use GlideRecord directly (since those run in the user’s browser). However, you can still check group membership by calling a server-side script via GlideAjax. The idea is to create a Script Include (or a GlideAjax script) that contains a function to perform the same GlideRecord check we did above, and then call that from the client.
For example, you might have a Script Include method isUserInGroup(userId, groupId) that returns "true" or "false". Your client script can use GlideAjax to call this Script Include asynchronously and get the result. This approach is useful for form validation or dynamic behaviors (e.g., showing a section only if a user is in a certain group) without exposing the logic to the client. Just be mindful of performance and security (the user might still need roles to make that AJAX call, or you might need to adjust ACLs if reading sys_user_grmember).
Built-in Conditions and ACLs: In some cases, you might not need to script at all. ServiceNow has some built-in ways to leverage group info. For instance, in Access Control lists (ACLs) or UI Actions, the condition builder allows checks like gs.getUser().isMemberOf('Group Name') as mentioned. Also, for certain platform features (like reference qualifiers on fields), you can sometimes filter users by group using an encoded query (though that might involve scripting as well, or conditions like javascript:... in the qualifier). There’s also an option in Flow Designer (if you have certain plugins) to check group membership, but a scripted approach is often more straightforward for developers.
Each of these methods has its place. The server-side GlideRecord method is the most direct for back-end logic and is the focus of this article, but the REST API is great for external or client calls, and GlideAjax is your friend for client-side needs within ServiceNow.
Common Issues and Troubleshooting Tips
When implementing and using the above solutions, you may encounter some common issues.
Here are some troubleshooting tips and best practices:
Correct Table and Field Usage: Ensure you are querying the right table and fields. The table is sys_user_grmember (often referred to as "Group Members"). The fields to query are user (which holds the user’s sys_id) and group (which holds the group’s sys_id). A common mistake is trying to query the user’s name or group name directly in this table without dot-walking. If you only have a username or group name, you can dot-walk in the query (e.g., gr.addQuery('user.user_name', 'joe')), but using sys_ids is usually safer and more precise. Remember that user names or group names might not be unique, whereas sys_id is unique.
Permissions (ACLs) on sys_user_grmember: By default, querying the sys_user_grmember table might require certain roles. If you run a GlideRecord query in a scoped application or as a non-admin user, you might hit permission issues. To troubleshoot, try running your script as an admin or in a background script first. If it only fails in a specific context (like in a portal script), consider the user’s roles.
You may need to grant access or use an alternative method (like a Script Include with an Elevated role via gs.getSession().impersonate for that check, or the built-in isMemberOf if dealing with the current user which respects their session roles). Always ensure your ACLs allow the script to read the Group Members table for the needed data.
Using gs.getUser().isMemberOf Correctly: If using the built-in isMemberOf() for the logged-in user, note that it can accept a group name or sys_id. However, it will not work on the client side and is only for server scripts (GlideSystem API). Also, be careful not to misuse it in certain contexts like in global scripts without proper checks. If you pass a group name that doesn’t exist, it will simply return false. If you pass an ID, ensure it’s the sys_id of a group. One more tip: gs.getUser() refers to the user running the script (often the logged-in user, or in some cases, system user for background jobs). So if you want to check membership of a user other than the current session user, isMemberOf won’t help — use GlideRecord as we did.
Link to: ServiceNow Client Scripts: Using the isMemberOf Function for User Group Validation
Client-side Limitations: Remember that client scripts (including those in Service Portal widgets) cannot directly query server tables. If you attempt to use GlideRecord in client script, it will not work and could throw an error. The solution, as discussed, is to use GlideAjax or to query via the REST API. If using GlideAjax, test your Script Include thoroughly and handle the callback on the client to avoid blocking the UI. Additionally, make sure the user has rights to call that GlideAjax (usually it runs in current user context, so reading sys_user_grmember might require the user to have certain roles unless you design the Script Include to run under elevated privileges carefully).
Performance Considerations: Checking group membership is usually a quick query, but if you find yourself doing it inside loops or for a large number of users/groups, consider optimizing. For example, if you need to check multiple groups at once for one user, you could query all that user’s group memberships in one go (one query returning multiple results) instead of checking one group at a time repeatedly. Conversely, to check if a user is in any one of many groups, you can use an OR query or the IN query operator on the GlideRecord. Also, if you are writing this logic in a frequently-run Business Rule or script, ensure it’s indexed (fields like user and group are indexed by default in sys_user_grmember, so queries are fast). Still, avoid unnecessary repetitive queries; sometimes caching the result or using the user’s roles (if groups are mainly for roles) might be more efficient in certain scenarios.
Troubleshooting “No Result” Scenarios: If your script is always saying the user is not in the group even when you believe they are, double-check the sys_ids you used. A common error is picking up the wrong sys_id (for example, confusing a user’s sys_id with their user_name, or using the group’s display name instead of sys_id in the query). You can verify IDs by navigating to the user or group record and copying the sys_id from the URL or using Show XML. Another possibility is that the user is in a subgroup or a role but not directly in that group – this script checks direct group membership only. ServiceNow does not automatically include membership of child groups or role inheritance in this table; each record is an explicit direct membership. If you need to handle hierarchical group membership, you would have to iterate through child groups or maintain separate logic.
Avoid Hard-Coding When Possible: While our example used hard-coded sys_ids in the script for illustration, in practice you’d want to avoid that. Use script parameters, system properties, or dynamically look up the group by name if you must (e.g., find the sys_id by querying sys_user_group where name = "Network Operations"). Hard-coding IDs can make maintenance harder if those records change. Also, if the script is intended for multiple environments (dev/test/prod), those sys_ids might differ, whereas group names usually stay consistent.
By keeping these tips in mind, you can minimize issues when implementing the membership check. Now, let’s wrap up with a brief summary and some best practices for managing group memberships in ServiceNow.
Conclusion and Best Practices
Checking if a user is a member of a particular group in ServiceNow is a common requirement for enforcing business logic, and it can be achieved either through a simple GlideRecord query on the sys_user_grmember table or via built-in utilities and APIs.
To recap the key steps:
Identify the User and Group you want to verify (using sys_ids for accuracy).
Use a server-side GlideRecord query on the sys_user_grmember table to see if a record exists linking that user to that group.
Alternatively, use built-in methods like gs.getUser().isMemberOf() for the logged-in user, or call the ServiceNow REST API to query membership remotely.
Handle the result (true/false) to drive your logic – for example, allow or deny an action, route a task, or display a message.
Troubleshoot with proper roles and query parameters if you run into issues, ensuring the script has access to the data and that you’re querying the correct values.
Beyond the technical steps, effective management of user-group memberships is vital. Here are some best practices to consider:
Maintain Group Integrity: Regularly review and update group memberships. Over time, users change roles or leave teams, so their group list should be pruned accordingly. “Periodically review group memberships to ensure users are only members of the groups necessary for their current job functions.” Removing unnecessary members helps tighten security and reduce clutter.
Delegate Group Ownership: Assign a responsible owner or manager for each group. As one best practice guide suggests, every group should have an active manager responsible for keeping the group’s purpose and membership up to date (with periodic reviews, e.g., quarterly). This ensures someone is accountable for who is in the group. Such managers can use reports or even automated notifications to verify memberships.
Use Groups for Role Assignment: ServiceNow recommends using groups to grant roles and not giving roles directly to users. This way, checking group membership can effectively control access (since roles come via group). It also simplifies onboarding/offboarding – you add or remove users from groups to grant or revoke permissions in bulk. Thus, design your access model such that being in a group implicitly gives the necessary rights (through roles or ACLs), which your scripts and flows can then leverage.
Implement Consistent Naming and Structure: Have a clear naming convention for groups and perhaps use the Group Type field to categorize groups (e.g., roles, assignment, approval groups). This can indirectly help when writing scripts – for example, you might query all groups of type "approval" to see if a user is in any of them. It also avoids confusion if two groups have similar names; using sys_ids in scripts avoids ambiguity, but good naming prevents mistakes in configuration and usage.
Plan for Scale: If your organization has many groups and users, consider solutions for bulk checking or reporting. Instead of writing many individual scripts to check membership, you could use a single utility (Script Include or even a scheduled job) to audit memberships. ServiceNow reporting or the Group Members related list on group records can show all users in a group. If you need to ensure a user is in a required group, you could automate a check when their profile is created or updated.
Next Steps: With this knowledge, you can implement group membership checks confidently. A good starting point is to try a simple check in a Background Script on a development instance – pick a user and group and use the GlideRecord method described to see the output. Then, incorporate this logic where needed: for example, in a Business Rule that prevents a record update unless the user is part of a certain support team, or in a UI Action that only shows for group members. Keep refining by handling edge cases (user or group not found, etc.). Also, consider building a reusable Script Include (e.g., GroupUtils with a method isUserInGroup(userSysId, groupSysId)) so that various scripts can call it rather than duplicating code.
By following these steps and best practices, you’ll ensure that user-group memberships in ServiceNow are checked accurately and efficiently, supporting your instance’s security and automation needs. Managing groups and memberships thoughtfully will lead to a more secure, organized, and maintainable ServiceNow implementation – which is beneficial for administrators and users alike.