Name

global.DiscoveryHyperVSensor

Description

Superclass for processing the WMI probe payload for Hyper-V discovery.

Script

var DiscoveryHyperVSensor = Class.create();
DiscoveryHyperVSensor.prototype = Object.extendsObject(DiscoverySensor, {
 
  process: function(result) {	   
      this.serverCI = this.getCmdbRecord();
     
  	//if we're dealing with WS2008 CI, get/create the associated hyperV CI
  	if(this.serverCI.sys_class_name == "cmdb_ci_win_server") {
  		this.winCI = this.serverCI;
  		this.serverCI = this.getHypervServerCi();

  		g_disco_functions.createRelationshipIfNotExists(this.serverCI, this.winCI, "Runs on::Runs");

  		// We previously did a couple of things in error: the Hyper-V host was marked as virtual
  		// and we created a 'virutalizes' relationship with it.  Checking for winCI.virtual will
  		// (hopefully) avoid the cost of checking to see if we need to clean up data in most cases.
  		if (this.winCI.virtual) {
  			var rel = g_disco_functions.relationshipExists(this.winCI, this.serverCI, "Virtualized by::Virtualizes");
  			if (rel) {
  				rel.deleteRecord();

  				// See if winCI is virtualized by anything else.  If not, clear the virtual flag.
  				var relationType = this.findCIRelationshipType("cmdb_rel_type", "Virtualized by::Virtualizes");
  				var gr = new GlideRecord("cmdb_rel_ci");
  				gr.addQuery("child", this.winCI);
  				gr.addQuery("type", relationType);
  				gr.query();
  				if (!gr.hasNext())
  					this.winCI.virtual = false;
  			}
  		}
  	}

  	//Subclass implements processResult()
     this.processResult(result);
  },
  
  getHypervServerCi: function() {
  	var fieldsToCopy = ["name", "os_service_pack", "manufacturer",
  			"model_id","short_description","os_address_width",
  			"os", "host_name", "ip_address", "location",
  			"chassis_type", "os_version", "assigned_to", "discovery_source",
  			"first_discovered", "last_discovered", "fqdn", "default_gateway"];
  	var gr = new GlideRecord("cmdb_ci_hyper_v_server");
  	var doUpdate = true;
  	gr.addQuery("windows_host", this.winCI.sys_id);
  	gr.query();

  	// Check if any work to do
  	var equals = true;
  	if (gr.next()) {
  		// Rec exists, see if need to update data discovered by Windows classify and OS Info sensors
  		for (var i=0; i < fieldsToCopy.length; i++) {
  			if (gr[fieldsToCopy[i]] != this.winCI[fieldsToCopy[i]]) {
  				equals = false;
  				break;
  			}
  		}
  		if (equals)
  			return gr;   // nothing to do
  	}

  	// Create or update rec inside a mutex
  	var mutexName = "HyperV Server with windows host " +  this.winCI.sys_id;
  	var mutex = new GlideSelfCleaningMutex(mutexName, mutexName);
  	mutex.setSpinWait(200);
  	if (!mutex.get())
  		throw "Could not acquire mutex " + mutexName;  // DB exception, or wait time expired
  	try {
  		gr.initialize();
  		gr.addQuery("windows_host", this.winCI.sys_id);
  		gr.query();
  		if (!gr.next()) {
  			doUpdate = false;
  
  			// Create the server CI
  			gr.initialize();
  			gr.windows_host = this.winCI.sys_id;
  		}
  	
  		// Copy over data discovered by Windows classify and OS Info sensors
  		for (var k=0; k < fieldsToCopy.length; k++)
  			gr[fieldsToCopy[k]] = this.winCI[fieldsToCopy[k]];

  		gr.serial_number = this.winCI.serial_number;
  		gr.virtual = true;
  		
  		
  		if (doUpdate)
  			gr.update();
  		else 
  			gr.insert();

  		var sourceName = gs.getProperty('glide.discovery.source_name', "ServiceNow");
  		var os = new ObjectSource(sourceName, gr.sys_class_name, gr.sys_id);
  		os.setValue("last_scan", new GlideDateTime().getDisplayValue());
  		os.process();

  		return gr;
  	} finally {
  		mutex.release();
  	}
 },
  
  extractUuid: function(instanceId) {
     var instanceIdRegex = /Microsoft:([^\\]*)\\?.*$/;
     var match = instanceIdRegex.exec(instanceId);
     return match ? match[1] : null;
  },

  type: 'DiscoveryHyperVSensor'
});

Sys ID

e8e23e75c350300031e65ad8cbba8f03

Offical Documentation

Official Docs: