Orphan Rule does not return the expected result
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
01-25-2023 07:35 AM
Hi,
I would like to get the CIs of some classes (server, application, service, process groups) which have not relations to other CIs.
To have good performance, I tried to create an orphan rule on Server Class, configured as the follow:
But in this way, I never find new orphaned records in table "cmdb_health_result".
I am sure that there are Servers which not have relations with other CIs in "cmdb_rel_ci".
Why this rule does not work?
Thanks & Regards, Giovanni
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
01-25-2023 07:41 AM
This will filter your orphan rule to say that in order for the Server to be an orphan it must have been last discovered by SGO-Dynatrace. On the surface that seems a bit restrictive, as you may have Servers coming in from other sources like Discovery. I wouldn't normally use Discovery Source as a condition for an orphan rule. The attribute to use is more to clarify which CIs you want to enforce the existence of a relationship on. Good attributes to filter this down might be Status/Operational Status and Environment.
The opinions expressed here are the opinions of the author, and are not endorsed by ServiceNow or any other employer, company, or entity.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
01-25-2023 09:51 AM - edited 01-25-2023 09:51 AM
I'd start by creating a report with the same conditions to get a subset of records that could have the problem. If that isn't obvious, you could modify the script below and see if there are any hits. At least then you would be troubleshooting from a known dataset. (This script is based on (I think) somewhere in this playbook - https://support.servicenow.com/kb?id=kb_article_view&sysparm_article=KB0829101.
///////////////////////////////////////////////////////////////////////////////////
// PROGRAM: delete_orphans Daniel L. Needles
// PURPOSE: CIs refer to other CIs. If there is no "mother ship", delete the CI.
///////////////////////////////////////////////////////////////////////////////////
CDK_CMDB_deduplicate.delete_orphans = function(command) {
/**
* Script used to list or delete orphan CIs
*/
// VALID IDENTIFICATION INDEXING?
if (command != 'listAll' && command != 'deleteAll') {
gs.log('ERROR: command must be either listAll or deleteAll');
return;
}
// *********************************** SETUP ************************************************************
var deleteCount = 4000;
var batchSize = 1000;
var deleteAll = false;
// ********************EDITING NOT REQUIRED PAST THIS POINT ********************************************
var deletionsCompleted = 0; // DO NOT CHANGE
var loopControl = true; // DO NOT CHANGE, var to delete multiple at least once
var resultString = 'CDK_CMDB_DeDuplicate Library Delete_Orphans Function\n\n';
var agg = new GlideAggregate('cmdb_rel_ci');
agg.addQuery('parent.sys_class_name', '').addOrCondition('child.sys_class_name', '');
agg.addAggregate('COUNT');
agg.query();
// LETS FIND OUT HOW MANY ORPHANS NEED TO BE DELETED
agg.next();
var deletionCandidates = agg.getAggregate("COUNT");
resultString += 'Found : ' + deletionCandidates + ' invalid relationships!\n';
if (command == 'listAll'){
resultString += 'To delete Orphaned Relationship, call with deleteAll, not listAll!\n';
} else {
//let's delete some records
var orphans = new GlideRecord('cmdb_rel_ci');
orphans.addQuery('parent.sys_class_name', '').addOrCondition('child.sys_class_name', '');
if (deleteCount == 0 && deleteAll){
orphans.setWorkflow(false);
orphans.setUseEngines(false);
orphans.deleteMultiple();
deletionsCompleted = deletionCandidates;
} else {
while (loopControl){
//delete n (deleteCount) records at a time
orphans.setLimit(batchSize);
orphans.query();
var deletedActualCount = orphans.getRowCount();
if (deletedActualCount!=0){
orphans.setWorkflow(false);
orphans.setUseEngines(false);
orphans.deleteMultiple();
deletionsCompleted += deletedActualCount;
if (deletionsCompleted >= deleteCount){
loopControl = false;
}
} else {
loopControl = false;
}
}
}
resultString += '\nSuccesfully deleted ' + deletionsCompleted + ' records!\n';
}
gs.print(resultString);
return(resultString);
};