Script Includes
CMDB Utilities
Reusable functions for working with Configuration Items (CIs) in the CMDB.
var CMDBUtils = Class.create();
CMDBUtils.prototype = {
/**
* Get all related CIs for a given CI
*
* @param {string} ciId - sys_id of CI
* @param {string} relationshipType - (Optional) Type of relationship
* @returns {Array} Array of related CI objects
*/
getRelatedCIs: function(ciId, relationshipType) {
var relatedCIs = [];
if (!ciId) {
return relatedCIs;
}
// Query CI relationships
var grRel = new GlideRecord('cmdb_rel_ci');
grRel.addQuery('parent', ciId);
grRel.addQuery('child', ciId);
grRel.setORCondition();
if (relationshipType) {
grRel.addQuery('type.name', relationshipType);
}
grRel.query();
while (grRel.next()) {
var relatedId = grRel.parent.toString() === ciId ?
grRel.child.toString() :
grRel.parent.toString();
var grCI = new GlideRecord('cmdb_ci');
if (grCI.get(relatedId)) {
relatedCIs.push({
sys_id: grCI.sys_id.toString(),
name: grCI.name.toString(),
sys_class_name: grCI.sys_class_name.toString(),
operational_status: grCI.operational_status.getDisplayValue(),
relationship_type: grRel.type.name.toString()
});
}
}
return relatedCIs;
},
/**
* Get CI hierarchy (parent and children)
*
* @param {string} ciId - sys_id of CI
* @param {number} levels - Number of levels to traverse (default: 3)
* @returns {object} {parents: Array, children: Array}
*/
getCIHierarchy: function(ciId, levels) {
levels = levels || 3;
return {
parents: this._getParentCIs(ciId, levels),
children: this._getChildCIs(ciId, levels)
};
},
/**
* Get parent CIs recursively
* @private
*/
_getParentCIs: function(ciId, levels, currentLevel) {
currentLevel = currentLevel || 1;
var parents = [];
if (currentLevel > levels) {
return parents;
}
var grRel = new GlideRecord('cmdb_rel_ci');
grRel.addQuery('child', ciId);
grRel.query();
while (grRel.next()) {
var parentId = grRel.parent.toString();
var grParent = new GlideRecord('cmdb_ci');
if (grParent.get(parentId)) {
parents.push({
sys_id: parentId,
name: grParent.name.toString(),
level: currentLevel
});
// Recursively get grandparents
var grandparents = this._getParentCIs(parentId, levels, currentLevel + 1);
parents = parents.concat(grandparents);
}
}
return parents;
},
/**
* Get child CIs recursively
* @private
*/
_getChildCIs: function(ciId, levels, currentLevel) {
currentLevel = currentLevel || 1;
var children = [];
if (currentLevel > levels) {
return children;
}
var grRel = new GlideRecord('cmdb_rel_ci');
grRel.addQuery('parent', ciId);
grRel.query();
while (grRel.next()) {
var childId = grRel.child.toString();
var grChild = new GlideRecord('cmdb_ci');
if (grChild.get(childId)) {
children.push({
sys_id: childId,
name: grChild.name.toString(),
level: currentLevel
});
// Recursively get grandchildren
var grandchildren = this._getChildCIs(childId, levels, currentLevel + 1);
children = children.concat(grandchildren);
}
}
return children;
},
/**
* Check if CI is affected by ongoing incidents or changes
*
* @param {string} ciId - sys_id of CI
* @returns {object} {hasIncidents: boolean, hasChanges: boolean, incidents: Array, changes: Array}
*/
checkCIImpact: function(ciId) {
var result = {
hasIncidents: false,
hasChanges: false,
incidents: [],
changes: []
};
if (!ciId) {
return result;
}
// Check for active incidents
var grIncident = new GlideRecord('incident');
grIncident.addQuery('cmdb_ci', ciId);
grIncident.addQuery('active', 'true');
grIncident.query();
while (grIncident.next()) {
result.hasIncidents = true;
result.incidents.push({
number: grIncident.number.toString(),
short_description: grIncident.short_description.toString(),
state: grIncident.state.getDisplayValue(),
priority: grIncident.priority.getDisplayValue()
});
}
// Check for active changes
var grChange = new GlideRecord('change_request');
grChange.addQuery('cmdb_ci', ciId);
grChange.addQuery('state', 'NOT IN', '-5,3,4,7'); // Not: Closed, Cancelled, etc.
grChange.query();
while (grChange.next()) {
result.hasChanges = true;
result.changes.push({
number: grChange.number.toString(),
short_description: grChange.short_description.toString(),
state: grChange.state.getDisplayValue(),
risk: grChange.risk.getDisplayValue()
});
}
return result;
},
/**
* Update CI operational status
*
* @param {string} ciId - sys_id of CI
* @param {string} newStatus - New operational status value
* @param {string} reason - Reason for status change
* @returns {boolean} True if updated successfully
*/
updateCIStatus: function(ciId, newStatus, reason) {
if (!ciId || !newStatus) {
return false;
}
var grCI = new GlideRecord('cmdb_ci');
if (!grCI.get(ciId)) {
gs.error('CMDBUtils: CI not found: ' + ciId);
return false;
}
var oldStatus = grCI.operational_status.toString();
grCI.operational_status = newStatus;
if (reason) {
grCI.comments = 'Status changed from ' + oldStatus + ' to ' + newStatus + '. Reason: ' + reason;
}
grCI.update();
gs.info('CMDBUtils: Updated CI ' + grCI.name + ' status from ' + oldStatus + ' to ' + newStatus);
return true;
},
/**
* Get CI with all related information
*
* @param {string} ciId - sys_id of CI
* @returns {object} Complete CI information
*/
getCIDetails: function(ciId) {
if (!ciId) {
return null;
}
var grCI = new GlideRecord('cmdb_ci');
if (!grCI.get(ciId)) {
return null;
}
return {
sys_id: grCI.sys_id.toString(),
name: grCI.name.toString(),
sys_class_name: grCI.sys_class_name.toString(),
operational_status: grCI.operational_status.getDisplayValue(),
u_criticality: grCI.u_criticality ? grCI.u_criticality.toString() : '',
owned_by: grCI.owned_by.getDisplayValue(),
managed_by: grCI.managed_by.getDisplayValue(),
supported_by: grCI.supported_by.getDisplayValue(),
location: grCI.location.getDisplayValue(),
impact: this.checkCIImpact(ciId),
relatedCIs: this.getRelatedCIs(ciId)
};
},
type: 'CMDBUtils'
};How to use it
1. Create a new Script Include 2. Set Name to "CMDBUtils" 3. Leave "Client callable" unchecked 4. Copy the code above 5. Use in Business Rules or Background Scripts to work with CIs Example usage: var cmdb = new CMDBUtils(); var ciDetails = cmdb.getCIDetails('ci_sys_id'); var impact = cmdb.checkCIImpact('ci_sys_id'); if (impact.hasIncidents) { gs.info('CI has active incidents'); }
Adapt the table names, fields, and conditions to your instance. Test the behavior in a development environment before using it in production.