Service Mapping
SkillDev toolsDiscover and validate service maps, identify mapping gaps, analyze service dependencies, and troubleshoot discovery patterns in ServiceNow ITOM
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the Service Mapping skill
What this skill tells your AI
The instructions your AI receives, as published by happy-technologies-llc/happy-platform-skills in skills/itom/service-mapping/SKILL.md and read by ahel’s review.
Overview
This skill provides a structured approach to managing service maps in ServiceNow ITOM Service Mapping. It covers:
- Discovering and viewing business service topologies
- Validating service map completeness and accuracy
- Identifying unmapped or orphaned CIs that should belong to a service
- Analyzing service dependency chains for impact assessment
- Reviewing and troubleshooting discovery patterns
- Detecting mapping gaps between services and their underlying infrastructure
When to use: When operations or service owners need to understand service topology, validate discovery results, troubleshoot broken service maps, or prepare for change impact analysis.
Plugin required: com.snc.service-mapping
Prerequisites
- Roles:
sm_admin,sm_user,itil, orcmdb_read - Access: Read/write to
cmdb_ci_service,svc_ci_assoc,sa_pattern,cmdb_rel_ci - Knowledge: Familiarity with CMDB CI classes, service mapping concepts, and discovery patterns
- Plugins:
com.snc.service-mappingandcom.snc.service-watchmust be activated
Procedure
Step 1: List Business Services and Their Health
Retrieve all defined business services to understand the service landscape.
Using MCP:
Tool: SN-Query-Table
Parameters:
table_name: cmdb_ci_service
query: active=true^ORDERBYname
fields: sys_id,name,number,operational_status,busines_criticality,owned_by,support_group,sys_class_name,sys_updated_on
limit: 50
Using REST API:
GET /api/now/table/cmdb_ci_service?sysparm_query=active=true^ORDERBYname&sysparm_fields=sys_id,name,number,operational_status,busines_criticality,owned_by,support_group,sys_class_name,sys_updated_on&sysparm_display_value=true&sysparm_limit=50
Operational Status Values:
| Value | Label | Description |
|---|---|---|
| 1 | Operational | Service is running normally |
| 2 | Repair | Under repair or maintenance |
| 3 | Non-Operational | Service is down |
| 4 | DR Standby | Disaster recovery standby |
Step 2: View Service Map CI Associations
Retrieve all CIs mapped to a specific business service to see its topology.
Using MCP:
Tool: SN-Query-Table
Parameters:
table_name: svc_ci_assoc
query: service=[service_sys_id]
fields: sys_id,service,ci_id,ci_id.name,ci_id.sys_class_name,ci_id.operational_status,port,type,is_manual
limit: 100
Using REST API:
GET /api/now/table/svc_ci_assoc?sysparm_query=service=[service_sys_id]&sysparm_fields=sys_id,service,ci_id,port,type,is_manual&sysparm_display_value=true&sysparm_limit=100
Step 3: Analyze Service Dependencies
Trace upstream and downstream dependencies for a business service.
Using MCP:
Tool: SN-Execute-Background-Script
Parameters:
description: Map service dependency tree for a business service
script: |
var svcId = '[service_sys_id]';
gs.info('=== SERVICE DEPENDENCY ANALYSIS ===');
// Upstream dependencies (services this service depends on)
gs.info('\n--- UPSTREAM DEPENDENCIES (Depends On) ---');
var upstream = new GlideRecord('cmdb_rel_ci');
upstream.addQuery('child', svcId);
upstream.addQuery('type.name', 'Depends on::Used by');
upstream.query();
while (upstream.next()) {
var parent = upstream.parent.getRefRecord();
gs.info('Depends on: ' + parent.name + ' (' + parent.sys_class_name + ') | Status: ' + parent.operational_status.getDisplayValue());
}
// Downstream dependencies (services that depend on this)
gs.info('\n--- DOWNSTREAM DEPENDENCIES (Used By) ---');
var downstream = new GlideRecord('cmdb_rel_ci');
downstream.addQuery('parent', svcId);
downstream.addQuery('type.name', 'Depends on::Used by');
downstream.query();
while (downstream.next()) {
var child = downstream.child.getRefRecord();
gs.info('Used by: ' + child.name + ' (' + child.sys_class_name + ') | Status: ' + child.operational_status.getDisplayValue());
}
// CI count by class
gs.info('\n--- CI COMPOSITION ---');
var ga = new GlideAggregate('svc_ci_assoc');
ga.addQuery('service', svcId);
ga.addAggregate('COUNT');
ga.groupBy('ci_id.sys_class_name');
ga.query();
while (ga.next()) {
gs.info('Class: ' + ga.ci_id.sys_class_name + ' | Count: ' + ga.getAggregate('COUNT'));
}
Using REST API:
# Upstream dependencies
GET /api/now/table/cmdb_rel_ci?sysparm_query=child=[service_sys_id]^type.name=Depends on::Used by&sysparm_fields=parent,type&sysparm_display_value=true
# Downstream dependencies
GET /api/now/table/cmdb_rel_ci?sysparm_query=parent=[service_sys_id]^type.name=Depends on::Used by&sysparm_fields=child,type&sysparm_display_value=true
Step 4: Review Discovery Patterns
Examine service mapping patterns to understand how CIs are discovered and mapped.
Using MCP:
Tool: SN-Query-Table
Parameters:
table_name: sa_pattern
query: active=true^ORDERBYname
fields: sys_id,name,description,ci_type,status,pattern_type,last_run,run_count,success_count,failure_count
limit: 50
Using REST API:
GET /api/now/table/sa_pattern?sysparm_query=active=true^ORDERBYname&sysparm_fields=sys_id,name,description,ci_type,status,pattern_type,last_run,run_count,success_count,failure_count&sysparm_display_value=true&sysparm_limit=50
Pattern Status Reference:
| Status | Description |
|---|---|
| Ready | Pattern is ready to run |
| Running | Pattern is currently executing |
| Completed | Last run completed successfully |
| Failed | Last run encountered errors |
| Disabled | Pattern is inactive |
Step 5: Identify Mapping Gaps
Find CIs that are not associated with any business service.
Using MCP:
Tool: SN-Execute-Background-Script
Parameters:
description: Find CIs with no service association (potential mapping gaps)
script: |
gs.info('=== SERVICE MAPPING GAP ANALYSIS ===');
// Find servers not mapped to any service
var ciClasses = ['cmdb_ci_server', 'cmdb_ci_app_server', 'cmdb_ci_db_instance', 'cmdb_ci_lb'];
for (var i = 0; i < ciClasses.length; i++) {
var className = ciClasses[i];
var gr = new GlideRecord(className);
gr.addQuery('operational_status', '1'); // Operational only
gr.addQuery('install_status', '1'); // Installed
gr.addJoinQuery('svc_ci_assoc', 'sys_id', 'ci_id', true); // LEFT JOIN - no association
gr.setLimit(20);
gr.query();
if (gr.getRowCount() > 0) {
gs.info('\n--- Unmapped ' + className + ' (showing up to 20) ---');
while (gr.next()) {
gs.info('CI: ' + gr.name + ' | IP: ' + gr.ip_address + ' | Location: ' + gr.location.getDisplayValue());
}
}
}
// Count total mapped vs unmapped
gs.info('\n--- MAPPING COVERAGE SUMMARY ---');
var totalCIs = new GlideAggregate('cmdb_ci');
totalCIs.addQuery('install_status', '1');
totalCIs.addAggregate('COUNT');
totalCIs.query();
totalCIs.next();
var total = parseInt(totalCIs.getAggregate('COUNT'));
var mappedCIs = new GlideAggregate('svc_ci_assoc');
mappedCIs.addAggregate('COUNT', 'DISTINCT', 'ci_id');
mappedCIs.query();
mappedCIs.next();
var mapped = parseInt(mappedCIs.getAggregate('COUNT', 'DISTINCT', 'ci_id'));
gs.info('Total installed CIs: ' + total);
gs.info('CIs mapped to services: ' + mapped);
gs.info('Unmapped CIs: ' + (total - mapped));
gs.info('Coverage: ' + Math.round((mapped / total) * 100) + '%');
Step 6: Validate Service Map Accuracy
Cross-reference service maps with active alerts to detect stale or incorrect mappings.
Using MCP:
Tool: SN-Execute-Background-Script
Parameters:
description: Cross-reference service maps with alerts
script: |
gs.info('=== SERVICE MAP VALIDATION ===');
var svc = new GlideRecord('cmdb_ci_service');
svc.addQuery('active', true);
svc.query();
while (svc.next()) {
// Check for alerts on CIs in this service
var assoc = new GlideRecord('svc_ci_assoc');
assoc.addQuery('service', svc.sys_id.toString());
assoc.query();
var alertCount = 0;
var staleCIs = 0;
while (assoc.next()) {
var ciId = assoc.ci_id.toString();
// Check for active alerts
var alert = new GlideAggregate('em_alert');
alert.addQuery('ci', ciId);
alert.addQuery('state', '!=', 'Closed');
alert.addAggregate('COUNT');
alert.query();
if (alert.next()) {
alertCount += parseInt(alert.getAggregate('COUNT'));
}
// Check for stale CIs (not updated in 90 days)
var ci = new GlideRecord('cmdb_ci');
if (ci.get(ciId)) {
var lastUpdate = new GlideDateTime(ci.sys_updated_on.toString());
var cutoff = new GlideDateTime();
cutoff.addDaysLocalTime(-90);
if (lastUpdate.before(cutoff)) {
staleCIs++;
}
}
}
if (alertCount > 0 || staleCIs > 0) {
gs.info('Service: ' + svc.name + ' | Active Alerts: ' + alertCount + ' | Stale CIs: ' + staleCIs);
}
}
Step 7: Troubleshoot Failed Discovery Patterns
Investigate patterns that have failed or produced unexpected results.
Using MCP:
Tool: SN-Query-Table
Parameters:
table_name: sa_pattern
query: status=Failed^ORactive=true^failure_count>0
fields: sys_id,name,ci_type,status,last_run,failure_count,success_count,error_message
limit: 20
Using REST API:
GET /api/now/table/sa_pattern?sysparm_query=status=Failed^ORactive=true^failure_count>0&sysparm_fields=sys_id,name,ci_type,status,last_run,failure_count,success_count,error_message&sysparm_display_value=true&sysparm_limit=20
Tool Usage
MCP Tools Reference
| Tool | When to Use |
|---|---|
SN-Query-Table | Query services, associations, patterns, relationships |
SN-Get-Record | Retrieve a single service or pattern record |
SN-Update-Record | Update service status or pattern configuration |
SN-Natural-Language-Search | Natural language searches like "services with failed patterns" |
SN-Execute-Background-Script | Dependency analysis, gap detection, bulk validation |
REST API Reference
| Endpoint | Method | Purpose |
|---|---|---|
/api/now/table/cmdb_ci_service | GET | Query business services |
/api/now/table/svc_ci_assoc | GET | Service-to-CI associations |
/api/now/table/sa_pattern | GET | Discovery patterns |
/api/now/table/cmdb_rel_ci | GET | CI relationships and dependencies |
/api/now/table/em_alert | GET | Cross-reference alerts with service CIs |
Best Practices
- Map Top-Down: Start with business services and map downward to infrastructure to ensure business context
- Validate After Discovery: Always review new pattern results before promoting to production service maps
- Monitor Coverage Metrics: Track the percentage of operational CIs mapped to services and set improvement targets
- Use Manual Entries Sparingly: Manual CI associations bypass discovery validation; prefer pattern-driven mapping
- Review Stale Mappings: Schedule quarterly reviews to remove decommissioned CIs from service maps
- Correlate with Change Management: Validate service maps after major changes to ensure topology accuracy
Troubleshooting
Pattern Fails with Credential Error
Cause: Discovery credentials are expired or lack permissions on the target host Solution: Verify credentials in Discovery Credentials module. Test SSH/WMI/SNMP connectivity from the MID Server.
CIs Missing from Service Map
Cause: Pattern does not cover the CI class or entry point is incorrect Solution: Review the pattern's entry point configuration. Check if the CI class has an applicable pattern. Verify network reachability from the MID Server.
Duplicate CIs in Service Map
Cause: Reconciliation rules not matching correctly, leading to duplicate CI creation
Solution: Review IRE (Identification and Reconciliation Engine) rules for the affected CI class. Check discovery_source field for conflicting sources.
Service Map Shows Stale Topology
Cause: Discovery schedule not running or pattern disabled
Solution: Verify the discovery schedule is active and running on the correct MID Server. Check sa_pattern.last_run to confirm execution.
Examples
Example 1: Full Service Topology Report
# 1. Get the business service
Tool: SN-Query-Table
Parameters:
table_name: cmdb_ci_service
query: name=Email Service
fields: sys_id,name,operational_status,busines_criticality,owned_by
limit: 1
# 2. Get all CIs in the service map
Tool: SN-Query-Table
Parameters:
table_name: svc_ci_assoc
query: service=[service_sys_id]
fields: ci_id,ci_id.name,ci_id.sys_class_name,ci_id.operational_status,port,type
limit: 200
# 3. Get dependency relationships
Tool: SN-Query-Table
Parameters:
table_name: cmdb_rel_ci
query: parent=[service_sys_id]^ORchild=[service_sys_id]
fields: parent,child,type
limit: 50
Example 2: Pre-Change Impact Assessment
# 1. Find all services affected by a CI undergoing change
Tool: SN-Query-Table
Parameters:
table_name: svc_ci_assoc
query: ci_id=[ci_sys_id]
fields: service,service.name,service.busines_criticality,type
limit: 20
# 2. For each affected service, get downstream consumers
Tool: SN-Query-Table
Parameters:
table_name: cmdb_rel_ci
query: parent=[service_sys_id]^type.name=Depends on::Used by
fields: child,child.name,child.sys_class_name
limit: 50
Example 3: Discovery Pattern Health Check
Tool: SN-Execute-Background-Script
Parameters:
description: Summary of pattern health
script: |
var ga = new GlideAggregate('sa_pattern');
ga.addQuery('active', true);
ga.addAggregate('COUNT');
ga.groupBy('status');
ga.query();
gs.info('=== PATTERN HEALTH SUMMARY ===');
while (ga.next()) {
gs.info('Status: ' + ga.status.getDisplayValue() + ' | Count: ' + ga.getAggregate('COUNT'));
}
Related Skills
itom/alert-analysis- Analyze alerts related to mapped servicesitom/observability-integration- Integrate external monitoring with service mapsitom/health-log-analytics- Monitor health of mapped service componentscmdb/relationship-mapping- CMDB relationship managementcmdb/impact-analysis- Business impact analysis using service maps
References
Signals
- GitHub stars
- 37
- Forks
- 13
- Last commit
- Jul 2026
Advanced
- Catalog kind
- skill
- Gateway key
service-mapping- Source
- github.com/happy-technologies-llc/happy-platform-skills