CMDB_CI_SERVER table location update based on discovery schedule location?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
02-07-2018 06:01 AM
Hi All,
i have a requirement to update the location of the server in CMDB_CI_SERVER table w.r.to discovery schedule location.
we have OOB feature to update the location ,but for some servers location is not updating ,so we want to customize this.
1) discovery schedule has location field with one value,the same should be updated for servers in CMDB_CI_SERVER table w.r.to their IP ranges.
2) for every discovery schedule we have defined some IP ranges .the server which is present in the above tables IP range will fall in the defined range.
i have written below business rule for this .script is executing fine,but location is not populating in the CMDB_CI_SERVER table.
business rule:
function location(){
var sysID ='8d7eb7ed4f302e842967ef4f0310c789';
var serverip = new GlideRecord('cmdb_ci_server');
serverip.addQuery('sys_id',sysID);
serverip.Query();
while(serverip.next()){
var iprange = new GlideRecord('discovery_range_item');
var discsche = new GlideRecord('discovery_schedule');
if( serverip.getValue('ip_address') >= iprange.getValue('start_ip_address') && serverip.getValue('ip_address') <= iprange.getValue('end_ip_address') ){
answer = iprange.getValue('schedule');
gs.log('answer');
continue;
}
if( answer = discsche.getValue('name')){
answer2 = discsche.getValue('location');
continue;
}
if( answer2 != serverip.getValue('location')){
answer3 = answer2;
}
serverip.location= answer3;
serverip.update();
}
}
can anyone help me on this.
Thanks,
kumar

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
02-21-2018 02:52 AM
Hello,
Some thought on this implementation:
1) Why would you do this on the cmdb_server table?
If any user other than the discovery edits the location field, this will override it. In addtion to this you could run into troubles, if the discovery prevents any other workflow from running.
2) Why not use the sensor/probe scripts?
You could instead just edit the sensor for your servers to set the current.location based on whatever value you wish. This way the data would be set BEFORE written into the database.
3) Whats with all of this answer stuff?
I don't quite understand the code you have provided. Now i know i am writing this a bit too direct, but i want to offer some critisism. The way you have set up the interaction of 3 ifs for one answer variable (which i can't even tell what it should contain) while only updating it under one of these conditions (or 2, since you are changing it on the way) is really confusing. Please change this.
For an example on a sensor you could change:
https://Yourinstance.service-now.com/nav_to.do?uri=%2Fdiscovery_sensor.do%3Fsys_id%3D6326caff0a0006bc4a6246ee74ddeae9%26sysparm_view%3D%26sysparm_record_target%3Ddiscovery_sensor%26sysparm_record_row%3D70%26sysparm_record_list%3DORDERBYzztextsearchyy%26sysparm_record_rows%3D199
This is for Windows OS. There you can see how current.COLUMN values are set after the probes have returned a result.
Greetings
Fabian
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
02-22-2018 07:57 AM
Hello,
1) all the servers discovered from discovery will store into CMDB_CI_SERVER table only. so after discovery run i want to update the location value w.r.to discovery location. our discoveries are running based on IP ranges and will run on weekends .for every one location field will be updated based on this.
2) all the discoveries have unique location values. so, we cannot use current.location
3) am new to scripting. based on my understanding i written the code.if you don't mind can you please correct my script and give the correct solution. it would be great help for me.
Thanks,
kumar

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
02-22-2018 08:55 AM
Hello,
no worries. I would like to suggest the way i would integrate it into the discovery before it updates the record to the cmdb. This needs some modification to the corresponding sensors of the discovery.
So the first thing to know is, that the discovery actually does not write into the cmdb_ci_server table but into tables extending this table. This is a list of all the tables possibly updated:
https://YOURINSTANCE.service-now.com/nav_to.do?uri=/discovery_classy_list.do%3Fsysparm_query%3DtableLIKEserver%26sysparm_first_row%3D1%26sysparm_view%3D
The link provided will lead you to the classifiers. Esantially what happens is that the Discovery finds and IP-Host and classifies it. Based of its classification it will use further probes and sensors to gather more information.
Now you could add the location to all of these sensors used. To do this check the desired classifiers and which probes they trigger. Each probe will trigger a sensor. Within the sensor you can then add a script setting the location.
Now to your business rule. If you want to use that i would suggest you first set up the trigger condition to only trigger if the updated by is the discovery user.
Now to the scripts content:
var location = location(current);
if(location)
{
current.location = location;
}
// since you call this within a before onChange business rule, no update() needed
function location(current){
// the sys ID is what i guess the sys id of the server you can instead use the current object within the business rule. To best do this, call this function and give it the current record
//var sysID ='8d7eb7ed4f302e842967ef4f0310c789';
var serverSysID = current.getUniqueValue();
// much easier here -> the current already is your server!
// var serverip = new GlideRecord('cmdb_ci_server');
// serverip.addQuery('sys_id',sysID);
// serverip.Query();
var serverIP = current.ip_address // Note: This field contains the ip adress of the cmdb_ci_server record. This can be named differently in your instance
var iprange = new GlideRecord('discovery_range_item');
// query missing -> This checks only for schedules which have a location and for ip ranges where the server would be in. This essentially does your while and if part
iprange.addNotNullQuery('iprange.schedule.location');
iprange.addQuery('start_ip_address', '<=', serverIP);
iprange.addQuery('end_ip_address', '>=', serverIP);
iprange.query();
// now since we know we only get your ip range the server is in and only the ones where the schedule has a location
if(iprange.next())
{
var location = iprange.schedule.location; // long live the dotwalk
return location;
}
}
I sadly don't have the time to check if this works, but it should. I hope all the comments are self explainatory. If not feel free to reply again.
NOTE: If you can dont loop over a queried glide record. Rather use the addQuery() functions to slim down the result of your query.
Hope this helps.
Greetings
Fabian

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
02-26-2018 03:42 AM
Hello,
Just checking back, did the solution work?
Greetings
Fabian