The critical insight here is that group membership lives in sys_user_grmember, not on the sys_user table itself. Most developers try to query users first, then filter by group — that's backwards and performs poorly. The membership table is the source of truth, and dot-walking from there to user fields is both faster and more reliable than trying to join the other direction.
When to use this
- When you need to process all members of a specific group for notifications, assignments, or bulk operations
- When building approval workflows that route to group members individually rather than the group itself
- When you need both user details and the ability to control whether inactive users are included
- When the group membership is relatively stable and you're not dealing with nested groups
When NOT to use this
- Don't use this for groups with nested membership — use
GlideUser.isMemberOf()or the Groups API instead - Don't use this in client scripts — wrap it in a Script Include and call via GlideAjax
- Don't use this when you only need to check if a specific user is in the group — query
sys_user_grmemberdirectly with both user and group filters - Don't use this for very large groups (1000+ members) without pagination — you'll hit performance issues
Key behaviors and gotchas
- Inactive users remain group members unless explicitly filtered out —
user.activedot-walk query is essential for most use cases - The
userfield is a reference, so dot-walking is safe — the foreign key constraint guarantees a valid user record exists - Domain separation applies to
sys_user_grmemberrecords — you'll only see memberships for groups in your current domain scope - ACL evaluation happens on the user records during dot-walking — users you can't read won't appear in results
- Always call
toString()onsys_idvalues when collecting into arrays — GlideElement objects behave unpredictably outside the query loop - The
sys_user_grmembertable has indexes on bothgroupanduserfields — queries by group are fast even for large instances
This pattern only returns direct group members. If your groups have nested membership (groups within groups), you'll miss users who inherit membership through parent groups. Use the Groups API or GlideUser methods for nested membership scenarios.
Enjoying this? Get one deep-dive per week.
Join 1,000+ ServiceNow pros — scripts, GlideRecord patterns, Flow Designer techniques, and career moves. Free.