CI Location Field Script

BenFan
Kilo Guru

I have a question regarding the location field for some of my company's Configuration Items (CIs) under the `cmdb_ci_list`. I posted about this issue on the ServiceNow Developer Forum [here](https://www.servicenow.com/community/developer-forum/the-location-field-for-some-of-our-cis-is-wrong...). Specifically, I discovered a scheduled job that updates the CI location based on the IP address (see "Location Issue-14"). In this job, there is a script (see "Location Issue-15").

 

I am considering updating the scheduled job with a new script. I would appreciate any thoughts on whether this new script will accomplish the task. Here’s the script:

// Helper function to safely convert IP to an unsigned 32-bit integer
function ipToInt(ip) {
    if (!ip) return -1;
    var parts = ip.trim().split('.');
    if (parts.length !== 4) return -1;
    
    // Using >>> 0 forces JavaScript to treat the result as an unsigned 32-bit integer
    return ((parseInt(parts[0], 10) << 24) | 
            (parseInt(parts[1], 10) << 16) | 
            (parseInt(parts[2], 10) << 8) | 
            parseInt(parts[3], 10)) >>> 0;
}

var updatedCount = 0;

// 1. Caching ranges in memory avoids running a nested loop query for every single CI
var ranges = [];
var rangeGR = new GlideRecord('ip_address_range');
rangeGR.query();
while (rangeGR.next()) {
    var startInt = ipToInt(rangeGR.start_ip + '');
    var endInt = ipToInt(rangeGR.end_ip + '');
    
    if (startInt !== -1 && endInt !== -1) {
        ranges.push({
            start: startInt,
            end: endInt,
            location: rangeGR.getValue('u_location_info') // Use getValue for references
        });
    }
}

// 2. Query Configuration Items needing evaluation
var ciGR = new GlideRecord('cmdb_ci');
ciGR.addNotNullQuery('ip_address');
// Optional: restrict query to only look at 10.14.x.x addresses for testing
// ciGR.addQuery('ip_address', 'STARTSWITH', '10.14.'); 
ciGR.query();

while (ciGR.next()) {
    var ciIp = ciGR.ip_address + '';
    var ciIpInt = ipToInt(ciIp);

    if (ciIpInt === -1) {
        gs.warn('[CI Location Update] Invalid IP on CI: ' + ciGR.getValue('name') + ' IP: [' + ciIp + ']');
        continue;
    }

    var matched = false;

    // Evaluate against the pre-loaded memory array
    for (var i = 0; i < ranges.length; i++) {
        var range = ranges[i];

        if (ciIpInt >= range.start && ciIpInt <= range.end) {
            matched = true;
            var newLocation = range.location;

            if (ciGR.getValue('location') != newLocation) {
                ciGR.setValue('location', newLocation);
                ciGR.update();
                updatedCount++;
                gs.info('[CI Location Update] CI "' + ciGR.getValue('name') + '" updated to location reference: ' + newLocation);
            }
            break; // Exit the loop once the first matching range is found
        }
    }

    if (!matched) {
        gs.info('[CI Location Update] No range match found for CI: ' + ciGR.getValue('name') + ' IP: ' + ciIp);
    }
}

gs.info('[CI Location Update] Execution complete. Total CIs updated: ' + updatedCount);

 

0 REPLIES 0