- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Wednesday
I am trying to create 3 reports,
1. To show servers that are in scope (Operational status = operation AND install status = installed, Environment=Production) (Count 1424)
2. Servers that are in scope mapped to a application , (used sysId is one of and called a Script include) - 559 seems realistic
3. Servers that are in Scope and not mapped to a application (used sysId is one of and called a Script include) -Number is more than servers that are in Scope
unMappedSrvr: function() {
var unMapdServer = [];
var inScopeQuery = gs.getProperty('inscope.server.app.mapping');// Used same property for Mapped servers too
var grSer2 = new GlideRecord('cmdb_ci_server');
//grSer2.addEncodedQuery(inScopeQuery ); //Seems like this failing , return count shows more thanCIs as per below scope , returns 9000~
grSer2.addEncodedQuery('install_status=1^environment=Production^operational_status=1'); //This is same filter as property, count is within scope, returns 751
grSer2.query();
while (grSer2.next()) {
var grCrel = new GlideRecord('cmdb_rel_ci');
grCrel.addQuery('child', grSer2.sys_id);
grCrel.addQuery('parent.sys_class_name', 'INSTANCEOF', 'cmdb_ci_service_discovered');
grCrel.query();
if (!grCrel.next()) {
unMapdServer.push(grSer2.sys_id.toString());
}
while (grCrel.next()) {
var grDrel = new GlideRecord('cmdb_rel_ci');
grDrel.addQuery('child', grCrel.parent);
grDrel.addQuery('parent.sys_class_name', 'cmdb_ci_business_app');
grDrel.query();
if (!grDrel.next()) {
unMapdServer.push(grSer2.sys_id.toString());
}
}
}
return unMapdServer.join(',');
},
Solved! Go to Solution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
yesterday
Hi @pardhiv ,
I can see that there is some logic issues in the code, which may cause the mismatching in count
First One: You are using two grCrel.next() function along with if and while here
" if (!grCrel.next()) { ...
while (grCrel.next()) {" which is wrong because consider below scenarios
Scenario 1: When Server has NO relations, it will work fine
| grCrel.next() | returns FALSE |
| IF block | runs → push server |
| while(grCrel.next()) | returns FALSE → loop skipped |
BUT
Scenario 2:Server HAS relations (example: 2 relations) Rel1, Rel2
IFCondition: !grCrel.next()here our rel1 is checked and cursor is moved to rel2.
while(grCrel.next()) here in the while loop rel2 is checked, so rel1 will always be skipped
Second One: You are pushing server inside the loop which is causing the duplicates
in this code portion:
while(..){
{if (!grDrel.next())
{ unMapdServer.push(grSer2.sys_id.toString()); }}
Consider: If server 1 has 3 discovered service, none of these services are linked to business application means the same server will be pushed 3 times in the array
So the corrected code is...
unMappedSrvr: function() {
var unMapdServer = [];
var inScopeQuery = gs.getProperty('inscope.server.app.mapping');
var grSer2 = new GlideRecord('cmdb_ci_server');
grSer2.addEncodedQuery('install_status=1^environment=Production^operational_status=1');
grSer2.query();
while (grSer2.next()) {
var isUnmapped = false;
var grCrel = new GlideRecord('cmdb_rel_ci');
grCrel.addQuery('child', grSer2.sys_id);
grCrel.addQuery('parent.sys_class_name', 'INSTANCEOF', 'cmdb_ci_service_discovered');
grCrel.query();
// 1 If NO discovered service relation
if (!grCrel.hasNext()) {
isUnmapped = true;
}
// 2 If discovered services exist, check business app mapping
while (!isUnmapped && grCrel.next()) {
var grDrel = new GlideRecord('cmdb_rel_ci');
grDrel.addQuery('child', grCrel.parent);
grDrel.addQuery('parent.sys_class_name', 'cmdb_ci_business_app');
grDrel.query();
// If service NOT linked to business app
if (!grDrel.hasNext()) {
isUnmapped = true;
break; // stop checking further services
}
}
// 3 Push only once
if (isUnmapped) {
unMapdServer.push(grSer2.sys_id.toString());
}
}
return unMapdServer.join(',');
}
Fix I applied
1) hasNext() ==> if (!grCrel.hasNext()) { ... } -> only checks if record exists, will not move the cursor to next record.
2)Handled duplicates ==> I avoided pushing the server inside the loop. Instead, I used a flag to mark the server as unmapped and immediately broke out of the loop when the condition was met. After exiting the loop, I pushed the server only once, which prevents duplicate entries.
I have made lot of efforts for this , if you find these useful please mark it as helpful and please accept my solution...
Best Regards,
SIVASANKARI S
ITOM Engineer
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Wednesday - last edited Wednesday
Hi @pardhiv ,
Are you getting results when you call the script in the background script?if yes
There is a checkbox called Sandbox Enabled on the script include table make it true and try
Regards
Chaitanya
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Wednesday - last edited Wednesday
-> gs.getProperty() won't work in client callable script include when it's called from a reporting filter condition as it will be executed on client side.
I have faced similar challenge earlier and was surprised to know this drawback.
Instead you can query sys_properties table with that property name and get the value and then use
I shared solution for this in 2022
Client Callable Script include issue as script filter in reports
Before: I am using gs.getProperty() and it didn't give result
After: I used GlideRecord to query properties and used and it worked
💡 If my response helped, please mark it as correct ✅ and close the thread 🔒— this helps future readers find the solution faster! 🙏
Ankur
✨ Certified Technical Architect || ✨ 9x ServiceNow MVP || ✨ ServiceNow Community Leader
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
yesterday
Hope you are doing good.
Did my reply answer your question?
💡 If my response helped, please mark it as correct ✅ and close the thread 🔒— this helps future readers find the solution faster! 🙏
Ankur
✨ Certified Technical Architect || ✨ 9x ServiceNow MVP || ✨ ServiceNow Community Leader
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
yesterday
I think the response you marked correct is not valid as that doesn't answer your gs.getProperty() question.
the solution I shared talks about workaround for gs.getProperty() as it doesn't work in script include report filter conditions.
Please mark appropriate response as correct so that it helps future members.
Ankur
✨ Certified Technical Architect || ✨ 9x ServiceNow MVP || ✨ ServiceNow Community Leader
