cmdb-patterns

CMDB Patterns for ServiceNow

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "cmdb-patterns" with this command: npx skills add groeimetai/snow-flow/groeimetai-snow-flow-cmdb-patterns

CMDB Patterns for ServiceNow

The Configuration Management Database (CMDB) is the foundation of ServiceNow ITSM, tracking all Configuration Items (CIs) and their relationships.

CMDB Architecture

CI Class Hierarchy

cmdb (Base) └── cmdb_ci (Configuration Item) ├── cmdb_ci_computer │ ├── cmdb_ci_server │ │ ├── cmdb_ci_linux_server │ │ ├── cmdb_ci_win_server │ │ └── cmdb_ci_unix_server │ └── cmdb_ci_pc_hardware ├── cmdb_ci_service │ ├── cmdb_ci_service_auto │ └── cmdb_ci_service_discovered ├── cmdb_ci_appl │ ├── cmdb_ci_app_server │ └── cmdb_ci_db_instance └── cmdb_ci_network_gear ├── cmdb_ci_netgear └── cmdb_ci_lb

Key CI Tables

Table Purpose Key Fields

cmdb_ci

Base CI table name, sys_class_name, operational_status

cmdb_ci_server

Servers ip_address, os, cpu_count, ram

cmdb_ci_service

Business Services service_classification, busines_criticality

cmdb_ci_appl

Applications version, install_directory

cmdb_rel_ci

CI Relationships parent, child, type

Creating Configuration Items

Basic CI Creation (ES5)

// Create a new server CI var ci = new GlideRecord("cmdb_ci_server") ci.initialize() ci.setValue("name", "PROD-WEB-001") ci.setValue("ip_address", "10.0.1.100") ci.setValue("os", "Linux Red Hat") ci.setValue("os_version", "8.5") ci.setValue("cpu_count", 8) ci.setValue("ram", 32768) ci.setValue("operational_status", 1) // Operational ci.setValue("install_status", 1) // Installed ci.setValue("used_for", "Production") ci.setValue("owned_by", "sys_id_of_owner") ci.setValue("support_group", "sys_id_of_group") var sysId = ci.insert()

CI with Discovery Source

// CI from Discovery var ci = new GlideRecord("cmdb_ci_linux_server") ci.initialize() ci.setValue("name", "discovered-server-001") ci.setValue("discovery_source", "ServiceNow") ci.setValue("first_discovered", new GlideDateTime()) ci.setValue("last_discovered", new GlideDateTime()) ci.setValue("ip_address", "10.0.2.50")

// Set classification ci.setValue("classification", "Production") ci.setValue("environment", "Production")

ci.insert()

CI Relationships

Relationship Types

Type Parent → Child Example

Runs on::Runs

App → Server ERP runs on PROD-DB-01

Depends on::Used by

Service → App HR Service depends on SAP

Contains::Contained by

Cluster → Server Cluster contains Node1

Hosted on::Hosts

VM → Hypervisor VM01 hosted on ESX01

Members::Member of

CI → Group Server member of Pool

Creating Relationships (ES5)

// Create relationship between CIs function createCIRelationship(parentSysId, childSysId, relationType) { // Find relationship type var relType = new GlideRecord("cmdb_rel_type") relType.addQuery("name", relationType) relType.query()

if (!relType.next()) { gs.error("Relationship type not found: " + relationType) return null }

// Check if relationship already exists var existing = new GlideRecord("cmdb_rel_ci") existing.addQuery("parent", parentSysId) existing.addQuery("child", childSysId) existing.addQuery("type", relType.getUniqueValue()) existing.query()

if (existing.next()) { gs.info("Relationship already exists") return existing.getUniqueValue() }

// Create new relationship var rel = new GlideRecord("cmdb_rel_ci") rel.initialize() rel.setValue("parent", parentSysId) rel.setValue("child", childSysId) rel.setValue("type", relType.getUniqueValue()) return rel.insert() }

// Usage createCIRelationship(appSysId, serverSysId, "Runs on::Runs")

Querying Relationships

// Find all servers an application runs on function getAppServers(appSysId) { var servers = []

var rel = new GlideRecord("cmdb_rel_ci") rel.addQuery("parent", appSysId) rel.addQuery("type.name", "Runs on::Runs") rel.query()

while (rel.next()) { var server = rel.child.getRefRecord() servers.push({ sys_id: server.getUniqueValue(), name: server.getValue("name"), ip_address: server.getValue("ip_address"), }) }

return servers }

// Find all dependencies of a service function getServiceDependencies(serviceSysId) { var deps = []

var rel = new GlideRecord("cmdb_rel_ci") rel.addQuery("parent", serviceSysId) rel.addQuery("type.name", "Depends on::Used by") rel.query()

while (rel.next()) { deps.push({ sys_id: rel.child.getUniqueValue(), name: rel.child.getDisplayValue(), class: rel.child.sys_class_name.toString(), }) }

return deps }

Impact Analysis

Upstream/Downstream Analysis

// Get all CIs affected by a CI outage (downstream impact) function getDownstreamImpact(ciSysId, depth) { if (typeof depth === "undefined") depth = 3

var impacted = [] var processed = {}

function traverse(sysId, currentDepth) { if (currentDepth > depth || processed[sysId]) return processed[sysId] = true

var rel = new GlideRecord("cmdb_rel_ci")
rel.addQuery("child", sysId)
rel.query()

while (rel.next()) {
  var parentId = rel.parent.toString()
  if (!processed[parentId]) {
    impacted.push({
      sys_id: parentId,
      name: rel.parent.getDisplayValue(),
      depth: currentDepth,
    })
    traverse(parentId, currentDepth + 1)
  }
}

}

traverse(ciSysId, 1) return impacted }

// Get all CIs this CI depends on (upstream dependencies) function getUpstreamDependencies(ciSysId, depth) { if (typeof depth === "undefined") depth = 3

var dependencies = [] var processed = {}

function traverse(sysId, currentDepth) { if (currentDepth > depth || processed[sysId]) return processed[sysId] = true

var rel = new GlideRecord("cmdb_rel_ci")
rel.addQuery("parent", sysId)
rel.query()

while (rel.next()) {
  var childId = rel.child.toString()
  if (!processed[childId]) {
    dependencies.push({
      sys_id: childId,
      name: rel.child.getDisplayValue(),
      depth: currentDepth,
    })
    traverse(childId, currentDepth + 1)
  }
}

}

traverse(ciSysId, 1) return dependencies }

Business Service Impact

// Find all business services impacted by a CI function getImpactedServices(ciSysId) { var services = [] var processed = {}

function findServices(sysId) { if (processed[sysId]) return processed[sysId] = true

// Check if this CI is a service
var ci = new GlideRecord("cmdb_ci")
if (ci.get(sysId)) {
  if (ci.sys_class_name.toString().indexOf("cmdb_ci_service") === 0) {
    services.push({
      sys_id: sysId,
      name: ci.getValue("name"),
      criticality: ci.getValue("busines_criticality"),
    })
  }
}

// Traverse upstream
var rel = new GlideRecord("cmdb_rel_ci")
rel.addQuery("child", sysId)
rel.query()

while (rel.next()) {
  findServices(rel.parent.toString())
}

}

findServices(ciSysId) return services }

CMDB Health & Data Quality

Orphan CI Detection

// Find CIs without relationships function findOrphanCIs(ciClass) { var orphans = []

var ci = new GlideRecord(ciClass || "cmdb_ci") ci.addQuery("operational_status", 1) // Operational only ci.query()

while (ci.next()) { var sysId = ci.getUniqueValue()

// Check for any relationships
var rel = new GlideRecord("cmdb_rel_ci")
rel.addQuery("parent", sysId).addOrCondition("child", sysId)
rel.setLimit(1)
rel.query()

if (!rel.hasNext()) {
  orphans.push({
    sys_id: sysId,
    name: ci.getValue("name"),
    class: ci.getValue("sys_class_name"),
  })
}

}

return orphans }

Stale CI Detection

// Find CIs not updated by discovery function findStaleCIs(daysOld) { if (typeof daysOld === "undefined") daysOld = 30

var stale = [] var cutoff = new GlideDateTime() cutoff.addDaysLocalTime(-daysOld)

var ci = new GlideRecord("cmdb_ci") ci.addQuery("operational_status", 1) ci.addQuery("last_discovered", "<", cutoff) ci.addNotNullQuery("last_discovered") ci.query()

while (ci.next()) { stale.push({ sys_id: ci.getUniqueValue(), name: ci.getValue("name"), last_discovered: ci.getValue("last_discovered"), }) }

return stale }

MCP Tool Integration

Available CMDB Tools

Tool Purpose

snow_create_ci

Create new CI with proper class

snow_cmdb_search

Search CIs with filters

snow_create_ci_relationship

Create CI relationships

snow_impact_analysis

Analyze CI impact

snow_get_ci_details

Get full CI information

snow_run_discovery

Trigger discovery

Example Workflow

// 1. Search for existing CI await snow_cmdb_search({ ci_class: "cmdb_ci_server", query: "name=PROD-WEB-001", include_relationships: true, })

// 2. Create new CI if not found await snow_create_ci({ ci_class: "cmdb_ci_linux_server", name: "PROD-WEB-002", ip_address: "10.0.1.101", operational_status: 1, })

// 3. Create relationship await snow_create_ci_relationship({ parent: appSysId, child: serverSysId, type: "Runs on::Runs", })

// 4. Impact analysis await snow_impact_analysis({ ci_sys_id: serverSysId, direction: "downstream", depth: 3, })

Best Practices

  • Use Correct CI Class - Always use most specific class (cmdb_ci_linux_server, not cmdb_ci)

  • Maintain Relationships - CIs without relationships have limited value

  • Discovery Alignment - Align manual CIs with discovery patterns

  • Operational Status - Keep status current (Operational, Retired, etc.)

  • Unique Identifiers - Use serial_number, asset_tag for uniqueness

  • Service Mapping - Connect CIs to business services

  • Regular Cleanup - Archive retired CIs, remove orphans

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

predictive-intelligence

No summary provided by upstream source.

Repository SourceNeeds Review
General

scheduled-jobs

No summary provided by upstream source.

Repository SourceNeeds Review
General

document-management

No summary provided by upstream source.

Repository SourceNeeds Review
General

reporting-dashboards

No summary provided by upstream source.

Repository SourceNeeds Review