About user-provisioning
A user lifecycle management skill for ServiceNow administrators, security administrators, and HR system integrators. It covers account creation, role and group assignments, changes, offboarding, and bulk operations, with job-function templates and least-privilege guidance.
Key features
- 01Create and update user accounts
- 02Assign roles and group memberships
- 03Configure access with job templates
- 04Handle offboarding and bulk operations
Use cases
- 01Provision accounts and access for new employees
- 02Adjust roles and groups after job changes
- 03Deactivate accounts and revoke access during offboarding
- 04Bulk-create users or assign group memberships
MCP support
Lists ServiceNow MCP tools for querying, creating, and updating user, role, and group records, and describes using batch operations and background scripts.
Install
Copy the command and run it in a terminal.
npx skills add https:/ / github.com/ happy-technologies-llc/ happy-platform-skills --skill user-provisioningAfter installing, type/user-provisioningin Claude Code to confirm it loaded.
Details
From the project READMEUser Provisioning
Overview
This skill provides comprehensive guidance for ServiceNow user lifecycle management:
- Creating new user accounts with proper attributes
- Assigning roles based on job function
- Managing group memberships
- Handling user deprovisioning and offboarding
- Bulk user operations
When to use: When onboarding new employees, changing user access, or offboarding departing employees.
Who should use this: System administrators, security administrators, and HR system integrators.
Prerequisites
- Roles:
admin,user_admin, orsecurity_admin - Access: sys_user, sys_user_group, sys_user_grmember, sys_user_has_role tables
- Knowledge: Understanding of your organization's role and group structure
- LDAP/SSO: If integrated, understand which attributes are managed externally
Key Tables
| Table | Purpose |
|---|---|
| sys_user | User records |
| sys_user_group | Group definitions |
| sys_user_grmember | Group membership associations |
| sys_user_has_role | Direct role assignments |
| sys_user_role | Role definitions |
| sys_group_has_role | Roles assigned to groups |
Procedure
Phase 1: User Creation
Step 1.1: Gather User Information
Required fields for new user creation:
| Field | Description | Example |
|---|---|---|
| user_name | Unique login ID | jsmith |
| first_name | First name | John |
| last_name | Last name | Smith |
| Email address | [email protected] | |
| employee_number | Employee ID | EMP-12345 |
| department | Department reference | IT Operations |
| manager | Manager reference | Manager's sys_id |
Step 1.2: Check for Existing User
Before creating, verify user doesn't already exist.
Using MCP:
Tool: SN-Query-Table
Parameters:
table_name: sys_user
query: user_name=jsmith^[email protected]
fields: sys_id,user_name,email,active
limit: 5
If user exists, proceed to role/group assignment instead.
Step 1.3: Create User Account
Using MCP:
Tool: SN-Create-Record
Parameters:
table_name: sys_user
data:
user_name: jsmith
first_name: John
last_name: Smith
email: [email protected]
employee_number: EMP-12345
title: Software Developer
department: [department_sys_id]
manager: [manager_sys_id]
location: [location_sys_id]
company: [company_sys_id]
phone: "+1-555-123-4567"
mobile_phone: "+1-555-987-6543"
active: true
locked_out: false
password_needs_reset: true
notification: 2 # Email notifications enabled
Using REST API:
POST /api/now/table/sys_user
Content-Type: application/json
{
"user_name": "jsmith",
"first_name": "John",
"last_name": "Smith",
"email": "[email protected]",
"employee_number": "EMP-12345",
"active": "true",
"password_needs_reset": "true"
}
Step 1.4: Set Initial Password
Using MCP (Background Script):
Tool: SN-Execute-Background-Script
Parameters:
script: |
var user = new GlideRecord('sys_user');
user.get('user_name', 'jsmith');
// Generate random password
var password = GlideSecureRandomUtil.getSecureRandomString(16);
user.setDisplayValue('user_password', password);
user.password_needs_reset = true;
user.update();
// Send welcome email (optional)
gs.eventQueue('user.created', user, password, '');
gs.info('User created. Initial password set. User will be prompted to reset on first login.');
description: Set initial password for new user
Phase 2: Role Assignment
Step 2.1: Understand Role Hierarchy
Common ServiceNow roles:
| Role | Description | Typical Users |
|---|---|---|
| itil | ITSM operations | Help desk, technicians |
| admin | Full administrative access | System admins |
| approver_user | Approval capabilities | Managers |
| catalog_admin | Catalog management | Catalog owners |
| knowledge | Knowledge base access | KB contributors |
| asset | Asset management | Asset managers |
| change_manager | Change management | Change managers |
| problem_manager | Problem management | Problem managers |
Step 2.2: Query Available Roles
Find Roles:
Tool: SN-Query-Table
Parameters:
table_name: sys_user_role
query: active=true
fields: sys_id,name,description,suffix
limit: 50
Find Role by Name:
Tool: SN-Query-Table
Parameters:
table_name: sys_user_role
query: name=itil
fields: sys_id,name,description
limit: 1
Step 2.3: Assign Role to User
Direct Role Assignment:
Tool: SN-Create-Record
Parameters:
table_name: sys_user_has_role
data:
user: [user_sys_id]
role: [role_sys_id]
state: active
inherited: false
Assign Multiple Roles (Batch):
Tool: SN-Batch-Create
Parameters:
records:
- table_name: sys_user_has_role
data:
user: [user_sys_id]
role: [itil_role_sys_id]
- table_name: sys_user_has_role
data:
user: [user_sys_id]
role: [knowledge_role_sys_id]
- table_name: sys_user_has_role
data:
user: [user_sys_id]
role: [approver_user_role_sys_id]
Step 2.4: Verify Role Assignment
Check User's Roles:
Tool: SN-Query-Table
Parameters:
table_name: sys_user_has_role
query: user=[user_sys_id]^state=active
fields: role,role.name,inherited,granted_by
limit: 50
Phase 3: Group Membership
Step 3.1: List Available Groups
Using MCP:
Tool: SN-List-SysUserGroups
Parameters:
limit: 100
Or query with filters:
Tool: SN-Query-Table
Parameters:
table_name: sys_user_group
query: active=true^type=itil
fields: sys_id,name,description,manager,email
limit: 50
Step 3.2: Add User to Group
Single Group Assignment:
Tool: SN-Create-Record
Parameters:
table_name: sys_user_grmember
data:
user: [user_sys_id]
group: [group_sys_id]
Multiple Group Assignments (Batch):
Tool: SN-Batch-Create
Parameters:
records:
- table_name: sys_user_grmember
data:
user: [user_sys_id]
group: [network_support_group_sys_id]
- table_name: sys_user_grmember
data:
user: [user_sys_id]
group: [it_operations_group_sys_id]
- table_name: sys_user_grmember
data:
user: [user_sys_id]
group: [change_advisory_board_sys_id]
Step 3.3: Verify Group Membership
Check User's Groups:
Tool: SN-Query-Table
Parameters:
table_name: sys_user_grmember
query: user=[user_sys_id]
fields: group,group.name,group.type
limit: 50
Check Group Members:
Tool: SN-Query-Table
Parameters:
table_name: sys_user_grmember
query: group=[group_sys_id]
fields: user,user.name,user.email
limit: 100
Phase 4: Role-Based Provisioning Templates
Step 4.1: Define Role Templates
Create standardized provisioning for common job functions:
IT Support Technician Template:
Roles: itil, knowledge
Groups: Service Desk, IT Support Tier 1
Notification: Email enabled
IT Manager Template:
Roles: itil, approver_user, report_user
Groups: IT Management, Change Advisory Board
Notification: Email enabled
Developer Template:
Roles: itil, personalize_dictionary
Groups: Development Team, Testing
Notification: Email enabled
Step 4.2: Automated Provisioning Script
Provision by Template:
Tool: SN-Execute-Background-Script
Parameters:
script: |
var userSysId = '[user_sys_id]';
var template = 'IT_SUPPORT_TECHNICIAN';
var templates = {
'IT_SUPPORT_TECHNICIAN': {
roles: ['itil', 'knowledge'],
groups: ['Service Desk', 'IT Support Tier 1']
},
'IT_MANAGER': {
roles: ['itil', 'approver_user', 'report_user'],
groups: ['IT Management', 'Change Advisory Board']
},
'DEVELOPER': {
roles: ['itil', 'personalize_dictionary'],
groups: ['Development Team', 'Testing']
}
};
var config = templates[template];
if (!config) {
gs.error('Unknown template: ' + template);
return;
}
// Assign roles
config.roles.forEach(function(roleName) {
var role = new GlideRecord('sys_user_role');
role.addQuery('name', roleName);
role.query();
if (role.next()) {
var userRole = new GlideRecord('sys_user_has_role');
userRole.initialize();
userRole.user = userSysId;
userRole.role = role.sys_id;
userRole.insert();
gs.info('Assigned role: ' + roleName);
}
});
// Assign groups
config.groups.forEach(function(groupName) {
var group = new GlideRecord('sys_user_group');
group.addQuery('name', groupName);
group.query();
if (group.next()) {
var membership = new GlideRecord('sys_user_grmember');
membership.initialize();
membership.user = userSysId;
membership.group = group.sys_id;
membership.insert();
gs.info('Added to group: ' + groupName);
}
});
gs.info('Provisioning complete for template: ' + template);
description: Provision user by job template
Phase 5: User Modification
Step 5.1: Update User Attributes
Update User Record:
Tool: SN-Update-Record
Parameters:
table_name: sys_user
sys_id: [user_sys_id]
data:
title: Senior Software Developer
department: [new_department_sys_id]
manager: [new_manager_sys_id]
location: [new_location_sys_id]
Step 5.2: Transfer User to New Group
Remove from Old Group:
Tool: SN-Query-Table
Parameters:
table_name: sys_user_grmember
query: user=[user_sys_id]^group=[old_group_sys_id]
fields: sys_id
limit: 1
# Then delete:
Tool: SN-Execute-Background-Script
Parameters:
script: |
var gr = new GlideRecord('sys_user_grmember');
gr.get('[membership_sys_id]');
gr.deleteRecord();
description: Remove user from group
Add to New Group:
Tool: SN-Create-Record
Parameters:
table_name: sys_user_grmember
data:
user: [user_sys_id]
group: [new_group_sys_id]
Step 5.3: Role Elevation/Removal
Remove Role:
Tool: SN-Query-Table
Parameters:
table_name: sys_user_has_role
query: user=[user_sys_id]^role=[role_sys_id]
fields: sys_id
limit: 1
# Then deactivate (preferred) or delete:
Tool: SN-Update-Record
Parameters:
table_name: sys_user_has_role
sys_id: [user_role_sys_id]
data:
state: revoked
Phase 6: Deprovisioning/Offboarding
Step 6.1: Immediate Actions
When an employee departs, take these steps immediately:
1. Deactivate User Account:
Tool: SN-Update-Record
Parameters:
table_name: sys_user
sys_id: [user_sys_id]
data:
active: false
locked_out: true
2. Revoke All Roles:
Tool: SN-Execute-Background-Script
Parameters:
script: |
var userSysId = '[user_sys_id]';
var gr = new GlideRecord('sys_user_has_role');
gr.addQuery('user', userSysId);
gr.addQuery('state', 'active');
gr.query();
var count = 0;
while (gr.next()) {
gr.state = 'revoked';
gr.update();
count++;
}
gs.info('Revoked ' + count + ' roles for user');
description: Revoke all user roles
3. Remove from All Groups:
Tool: SN-Execute-Background-Script
Parameters:
script: |
var userSysId = '[user_sys_id]';
var gr = new GlideRecord('sys_user_grmember');
gr.addQuery('user', userSysId);
gr.query();
var count = 0;
while (gr.next()) {
gr.deleteRecord();
count++;
}
gs.info('Removed user from ' + count + ' groups');
description: Remove user from all groups
Step 6.2: Reassign Owned Records
Find Records Owned by User:
Tool: SN-Query-Table
Parameters:
table_name: incident
query: assigned_to=[user_sys_id]^active=true
fields: number,short_description,state
limit: 100
Tool: SN-Query-Table
Parameters:
table_name: change_request
query: assigned_to=[user_sys_id]^stateNOT IN3,4,7
fields: number,short_description,state
limit: 100
Bulk Reassignment:
Tool: SN-Execute-Background-Script
Parameters:
script: |
var departingUser = '[departing_user_sys_id]';
var newAssignee = '[new_assignee_sys_id]';
var tables = ['incident', 'change_request', 'problem', 'sc_task'];
tables.forEach(function(tableName) {
var gr = new GlideRecord(tableName);
gr.addQuery('assigned_to', departingUser);
gr.addQuery('active', true);
gr.query();
var count = 0;
while (gr.next()) {
gr.assigned_to = newAssignee;
gr.work_notes = 'Reassigned due to employee departure';
gr.update();
count++;
}
gs.info('Reassigned ' + count + ' ' + tableName + ' records');
});
description: Reassign all active records from departing user
Step 6.3: Document Offboarding
Create Offboarding Record:
Tool: SN-Create-Record
Parameters:
table_name: sys_user_task
data:
short_description: "Offboarding: [User Name] - [Employee ID]"
description: |
Employee Offboarding Checklist:
[x] User account deactivated
[x] All roles revoked
[x] Removed from all groups
[x] Active tickets reassigned
Departure Date: 2026-02-06
Reason: [Resignation/Termination/Transfer]
IT Actions:
- [ ] VPN access revoked
- [ ] Email forwarding configured
- [ ] Hardware returned
- [ ] Access badges collected
Manager: [Manager Name]
HR Contact: [HR Name]
assigned_to: [hr_admin_sys_id]
priority: 2
Phase 7: Bulk Operations
Step 7.1: Bulk User Creation
Create Multiple Users:
Tool: SN-Batch-Create
Parameters:
records:
- table_name: sys_user
data:
user_name: user1
first_name: Alice
last_name: Johnson
email: [email protected]
active: true
- table_name: sys_user
data:
user_name: user2
first_name: Bob
last_name: Williams
email: [email protected]
active: true
- table_name: sys_user
data:
user_name: user3
first_name: Carol
last_name: Davis
email: [email protected]
active: true
Step 7.2: Bulk Role Assignment
Assign Role to Multiple Users:
Tool: SN-Execute-Background-Script
Parameters:
script: |
var userIds = ['[user1_sys_id]', '[user2_sys_id]', '[user3_sys_id]'];
var roleName = 'itil';
var role = new GlideRecord('sys_user_role');
role.addQuery('name', roleName);
role.query();
if (role.next()) {
userIds.forEach(function(userId) {
var userRole = new GlideRecord('sys_user_has_role');
userRole.initialize();
userRole.user = userId;
userRole.role = role.sys_id;
userRole.insert();
});
gs.info('Assigned ' + roleName + ' role to ' + userIds.length + ' users');
}
description: Bulk role assignment
Step 7.3: Bulk Group Membership
Add Multiple Users to Group:
Tool: SN-Execute-Background-Script
Parameters:
script: |
var groupName = 'Network Support';
var userIds = ['[user1_sys_id]', '[user2_sys_id]', '[user3_sys_id]'];
var group = new GlideRecord('sys_user_group');
group.addQuery('name', groupName);
group.query();
if (group.next()) {
userIds.forEach(function(userId) {
var member = new GlideRecord('sys_user_grmember');
member.initialize();
member.user = userId;
member.group = group.sys_id;
member.insert();
});
gs.info('Added ' + userIds.length + ' users to ' + groupName);
}
description: Bulk group membership assignment
Tool Usage Summary
| Operation | MCP Tool | Purpose |
|---|---|---|
| List Users | SN-List-SysUsers | Get all users |
| List Groups | SN-List-SysUserGroups | Get all groups |
| Create User | SN-Create-Record | Create new user |
| Update User | SN-Update-Record | Modify user attributes |
| Query | SN-Query-Table | Search users, roles, groups |
| Bulk Create | SN-Batch-Create | Create multiple records |
| Script | SN-Execute-Background-Script | Complex operations |
Best Practices
- Principle of Least Privilege: Assign minimum roles needed for job function
- Use Groups for Roles: Assign roles to groups, add users to groups
- Document Role Assignments: Maintain documentation of who has what access
- Regular Access Reviews: Audit user access quarterly
- Immediate Offboarding: Deactivate accounts same day as departure
- Use Templates: Standardize provisioning with job function templates
- Avoid Direct Role Assignment: Prefer group-based role inheritance
- Lock, Don't Delete: Deactivate users instead of deleting for audit trail
Troubleshooting
User Can't Log In
Symptom: User receives "invalid credentials" error Causes:
- Account inactive
- Account locked out
- Password expired Solution:
Tool: SN-Query-Table
Parameters:
table_name: sys_user
query: user_name=[username]
fields: active,locked_out,password_needs_reset,failed_attempts
User Missing Expected Access
Symptom: User can't access expected modules or records Causes:
- Role not assigned
- Role revoked or expired
- Group membership missing Solution:
Tool: SN-Query-Table
Parameters:
table_name: sys_user_has_role
query: user=[user_sys_id]^state=active
fields: role.name,inherited,granted_by
Inherited Roles Not Appearing
Symptom: User in group but not getting group's roles Causes:
- Group role inheritance disabled
- Group inactive Solution:
Tool: SN-Query-Table
Parameters:
table_name: sys_user_group
query: sys_id=[group_sys_id]
fields: name,active,roles
Related Skills
admin/batch-operations- Bulk user operationssecurity/acl-management- ACL configurationadmin/script-execution- Automated provisioning scriptsitsm/change-management- Change process for access changes