VMWare and Serial Numbers

tony_fugere
Mega Guru

Client came to me with a need to modify Discovery. All of their ESX Servers had a VMWare serial number (e.g. 12345c1c-1234-123a-123b-b1c23f4c5678). They want the actual server's hardware manufacturer serial number instead. SSH and SNMP were not an option. So, we did some digging on "The Google" and came across a PowerShell script that leverages the VMWare PowerCLI and CIM to extract the hardware serial number. Credit for that goes to RvdNieuwendijk on http://communities.vmware.com/message/1767984.

First, we have to setup the MID server a bit differently. The MID needs:

  • VMWare vSphere PowerCLI installed
  • A custom PowerShell Module created

Custom PowerShell Module


The probe uses this. In this case, C:\Service-now\agent\lib\vCenterConnect.psm1 is being used. This is important because it stores (in clear text) the password used to log onto the vCenter host. I know, I know, some of you are cringing right now. We figured that it is better to store it on the MID in a "secure" location instead of trying to pass it over the Internet in the probe parameter. We're still looking for a solution around that to keep it encrypted or more secure, but this met our needs for now. You'll see the use of "vCenterConnect -server $computer > $null" in the probe parameter which logs you into the vCenter to perform the rest of the functions.


C:\Service-now\agent\lib\vCenterConnect.psm1


function vCenterConnect([string]$server) {
connect-viserver -server $server -user USERNAME -Password PASSWORD
}
Export-ModuleMember vCenterConnect







Probe

Be sure to add this probe to the Triggers Probe list on the VMWare vCenter probe.


Name: VMWare Serial Number

Probe Type: Probe

ECC Queue Topic: Powershell

ECC Queue Name: VmWare Serial Number

Used by Discovery: true



Probe Parameter:

Name: VMWareSerial.ps1

Set-ExecutionPolicy Unrestricted
Add-PSSnapin VMware.VimAutomation.Core
Import-Module "C:\Service-now\agent\lib\vCenterConnect.psm1"

function Get-VMHostWSManInstance {
param (
[Parameter(Mandatory=$TRUE,HelpMessage="VMHosts to probe")]
[VMware.VimAutomation.ViCore.Impl.V1.Inventory.VMHostImpl[]]
$VMHost,

[Parameter(Mandatory=$TRUE,HelpMessage="Class Name")]
[string]
$class,

[switch]
$ignoreCertFailures,

[System.Management.Automation.PSCredential]
$credential=$null
)

$omcBase = "http://schema.omc-project.org/wbem/wscim/1/cim-schema/2/"
$dmtfBase = "http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/"
$vmwareBase = "http://schemas.vmware.com/wbem/wscim/1/cim-schema/2/"

if ($ignoreCertFailures) {
$option = New-WSManSessionOption -SkipCACheck -SkipCNCheck -SkipRevocationCheck
} else {
$option = New-WSManSessionOption
}
foreach ($H in $VMHost) {
Try
{
if ($credential -eq $null) {
$hView = $H | Get-View -property Value
$ticket = $hView.AcquireCimServicesTicket()
$password = convertto-securestring $ticket.SessionId -asplaintext -force
$credential = new-object -typename System.Management.Automation.PSCredential -argumentlist $ticket.SessionId, $password
}
$uri = "https`://" + $h.Name + "/wsman"
if ($class -cmatch "^CIM") {
$baseUrl = $dmtfBase
} elseif ($class -cmatch "^OMC") {
$baseUrl = $omcBase
} elseif ($class -cmatch "^VMware") {
$baseUrl = $vmwareBase
} else {
throw "Unrecognized class"
}
Get-WSManInstance -Authentication basic -ConnectionURI $uri -Credential $credential -Enumerate -Port 443 -UseSSL -SessionOption $option -ResourceURI "$baseUrl/$class"
}
Catch [system.exception]
{
}
}
}

vCenterConnect -server $computer > $null

Get-VMHost | ForEach-Object {
$VMHost = $_
$PhysicalPackage = Get-VMHostWSManInstance -VMHost $_ -class CIM_PhysicalPackage -ignoreCertFailures | Where-Object {$_.ElementName -eq "Chassis"}
$Report = "" | Select-Object -Property VMHost,SerialNumber
$Report.VMHost = $VMHost.Name
$Report.SerialNumber = $PhysicalPackage.SerialNumber
$Report
}



Sensor:

Name: VMWare Serial Number (Sensor)

Reacts to Probe: VMWare Serial Number

Sensor Type: Sensor

Sensor type: Javascript

Active: true (obviously)
Description: Get actual server hardware serial numbers

Script:
new DiscoverySensor({
process: function(result) {
var foundStart = false;
var lines = result.output.toString().split('\n');
for(var i = 0, len = lines.length; i < len; i++) {
var line = lines;
if(/^VMHost +SerialNumber$/.test(line)) {
foundStart = true;
}
if(foundStart && /^[a-z0-9]/.test(line)) {
var parts = line.replace(/ +/, ' ').split(' ');
var server = parts[0];
var serial = parts[1];
var computer = new GlideRecord('cmdb_ci_esx_server');
server = server.substring(0, server.indexOf('.'));
computer.addEncodedQuery('nameSTARTSWITH' + server);
computer.query();
if(computer.next()) {
computer.serial_number = serial;
computer.update();
}
}
}
},

type: "DiscoverySensor"

});

 

2 REPLIES 2

mdillmann
ServiceNow Employee
ServiceNow Employee

Hi Tony,


really good stuff. I am working on a PoV where we need to read out Tags assigned to a VM via a PowerCLI powershell probe.



Did you ever find out how to make the credentials-piece more secure or how to access the ServiceNow discovery crendtials table from a Powershell probe ?



Thanks,


-Markus


Markus,



Unfortunately, I have not worked on or touched this one since I posted it. A quick Google search shows that there should be a way to accomplish a more secure credential storage.



VMware KB: Creating a VMware credential store file for third party plugins



New-VICredentialStoreItem



Tinker with those two and see if you can one-up my solution!