Product Announcements

Hardware Health Monitoring via CIM, part 2

In our last post, we looked at some of the basics of CIM technology and a very basic script that can dump out the version of ESX the system is running.  Now lets take a deeper dive into some of the hardware asset information that's available.

Before we look at the code, lets talk a little about where this data comes from.  The data we'll be looking at in this installment comes from SMBIOS, which is an industry standard extension to BIOS that exposes basic system management information.  Just about every system you can buy these days has some amount of SMBIOS information available.  Some examples of SMBIOS information are CPU details, memory modules, and chassis information.  This information maps into a number of SMASH profiles, such as DSP1022 – CPU profile, DSP1026 – System Memory Profile, and DSP1011 – Physical Asset Profile.

In this example, we'll start to abstract thins out a little more so we can start to build some reusable parts for future examples.  The three classes we'll look at are OMC_Processor, OMC_PhysicalMemory, and OMC_Chassis.

#!/usr/bin/env python

# First import the various python modules we'll need 
import pywbem
import os
import sys
from optparse import OptionParser

# Simple routine to display an instance
def printInstance(instance):
   print instance.classname
   for propertyName in sorted(instance.keys()):
      if instance[propertyName] is None:
         # skip over null properties
         continue
      print '%30s = %s' % (propertyName, instance[propertyName])

# Simple function to dump out asset information
def dumpAssetInformation(server, username, password):
   client = pywbem.WBEMConnection('https://'+options.server <https://%27+options.server> ,
                                  (options.username, options.password),
                                  'root/cimv2')
   list = []
   for classname in ['OMC_Chassis', 'OMC_PhysicalMemory', 'OMC_Processor']:
      list.extend(client.EnumerateInstances(classname))
   if len(list) == 0:
      print 'Error: Unable to locate any instances'
   else:
      for instance in list:
         printInstance(instance)

if __name__ == '__main__':
   # Some command line argument parsing gorp to make the script a little more
   # user friendly.
   usage = '''Usage: %prog [options]
      This program will dump some basic asset information from an ESX host
      specified by the -s option.'''
   parser = OptionParser(usage=usage)
   parser.add_option('-s', '–server', dest='server',
                     help='Specify the server to connect to')
   parser.add_option('-u', '–username', dest='username',
                     help='Username (default is root)')
   parser.add_option('-p', '–password', dest='password',
                     help='Password (default is blank)')
   (options, args) = parser.parse_args()
   if options.server is None:
      print 'You must specify a server to connect to.  Use –help for usage'
      sys.exit(1)
   if options.username is None:
      options.username = 'root'
   if options.password is None:
      options.password = ''

   dumpAssetInformation(options.server, options.username, options.password)

And here's some example output on one of my test rigs:


OMC_Chassis
Caption = Chassis
ChassisPackageType = 17
ChassisTypeDescription = Main Server Chassis
CreationClassName = OMC_Chassis
ElementName = Chassis
IpmiNodeCount = 1
LockPresent = True
Manufacturer = Dell Inc.
Model = PowerEdge 2900
OperationalStatus = [0L]
OtherIdentifyingInfo = Asset Tag: MyAssetTag
PackageType = 3
PoweredOn = True
RemovalConditions = 0
SerialNumber = 5TCXDD1
Status = Unknown
StatusDescriptions = [u'unknown']
Tag = 23.0
uuid = 44454c4c-5400-1043-8058-b5c04f444431


OMC_PhysicalMemory
Capacity = 1073741824
Caption = DIMM1
CreationClassName = OMC_PhysicalMemory
DataWidth = 64
Description = DIMM1
ElementName = DIMM1
FormFactor = 8
IsSpeedInMhz = True
Manufacturer = 80CE7FB380CE
MaxMemorySpeed = 667
MemoryType = 23
OperationalStatus = [0L]
PartNumber = M395T2953EZ4-CE66
SerialNumber = 0406A979
Speed = 1
Tag = 32.0
TotalWidth = 72

OMC_PhysicalMemory
Capacity = 1073741824
Caption = DIMM2
CreationClassName = OMC_PhysicalMemory
DataWidth = 64
Description = DIMM2
ElementName = DIMM2
FormFactor = 8
IsSpeedInMhz = True
Manufacturer = 80CE7FB380CE
MaxMemorySpeed = 667
MemoryType = 23
OperationalStatus = [0L]
PartNumber = M395T2953EZ4-CE66
SerialNumber = 0406A972
Speed = 1
Tag = 32.1
TotalWidth = 72

OMC_PhysicalMemory
Capacity = 1073741824
Caption = DIMM3
CreationClassName = OMC_PhysicalMemory
DataWidth = 64
Description = DIMM3
ElementName = DIMM3
FormFactor = 8
IsSpeedInMhz = True
Manufacturer = 80CE7FB380CE
MaxMemorySpeed = 667
MemoryType = 23
OperationalStatus = [0L]
PartNumber = M395T2953EZ4-CE66
SerialNumber = 0406AA1D
Speed = 1
Tag = 32.2
TotalWidth = 72

OMC_PhysicalMemory
Capacity = 1073741824
Caption = DIMM4
CreationClassName = OMC_PhysicalMemory
DataWidth = 64
Description = DIMM4
ElementName = DIMM4
FormFactor = 8
IsSpeedInMhz = True
Manufacturer = 80CE7FB380CE
MaxMemorySpeed = 667
MemoryType = 23
OperationalStatus = [0L]
PartNumber = M395T2953EZ4-CE66
SerialNumber = 0406AA2B
Speed = 1
Tag = 32.3
TotalWidth = 72

OMC_Processor
CPUStatus = 0
Caption = CPU1
Characteristics = [2L, 4L, 6L]
CreationClassName = OMC_Processor
CurrentClockSpeed = 1600
DataWidth = 64
Description = CPU1
DeviceID = 3.1
ElementName = CPU1
EnabledDefault = 2
EnabledProcessorCharacteristics = [2L, 2L, 2L]
EnabledState = 2
ExternalBusClockSpeed = 1066
Family = 179
HealthState = 5
IdentifyingDescriptions = [u'Brand ID']
MaxClockSpeed = 3600
ModelName = Intel(R) Xeon(R) CPU E5310 @ 1.60GHz
NumberOfEnabledCores = 4
OperationalStatus = [2L]
OtherIdentifyingInfo = [u'0x ff']
RequestedState = 12
Stepping = 7
SystemCreationClassName = OMC_UnitaryComputerSystem
SystemName = 44454c4c-5400-1043-8058-b5c04f444431
TransitioningToState = 12
UpgradeMethod = 20


The complete example code is also attached for easy downloading.

In our next installment we'll take a look at some of the information available from IPMI.