The following is the first of a multi-part posting, once again from Daniel Hiltgen, one of the senior developers on the ESXi product.

Starting in ESX 3.5, VMware has leveraged the industry standard CIM technologies to enable interoperable remote hardware health monitoring and 3rd party extensibility on both the ESX and ESXi platforms.  This post is the first in a series where we'll dive into more detail on how you can use this capability of ESX to monitor the health of your hosts and get basic hardware asset information.

Before we dive into the sample code, lets spend a little time discussing the relevant technology.  CIM (Common Information Model) is an industry standard defined by the DMTF (Distributed Management Task Force).  There are two primary aspects to these standards – the first is the data model, and the second is the wire protocol we use to transfer that data over the network.  Lets look at the data model first.

CIM defines a way to represent systems data in an object oriented fashion, described in a format called MOF (managed object format). The DMTF defines "well defined" schemas (collections of classes) that cover a broad spectrum of management topics. Unfortunately given their large breadth and extensive use of generalized abstractions, it's possible to build two implementations in isolation covering the same topic that use different official CIM classes, properties and methods which makes it difficult to achieve interoperability.  To address this limitation and foster better interoperability between implementations, the DMTF also defines specifications called Management Profiles covering specific management topics, which define in more concrete detail which classes, properties, and methods from the standard schema that an implementation must support to be considered compatible with that profile.  A few examples of profiles VMware supports are: DSP1022 – CPU Profile, DSP1009 – Sensor Profile.  To help organize this large and growing set of profiles, the DMTF has grouped them together under initiatives.  One such example is called SMASH (Systems Management Architecture for Server Hardware).  Given the focus on server hardware for ESX, VMware has implemented a number of profiles from SMASH.  You can see the specific profiles, classes, properties, and methods we have implement in the VMware SMASH API documentation.

Now that we have some data, how do we actually get at it over the network?  The DMTF has defined two primary wire protocols that you can use to transfer data over the network.  The older protocol is called CIM XML over HTTP. The newer protocol utilizes a SOAP based transport, and is called WS-Management.  VMware supports both of these protocols, and libraries are available for most popular languages.  For the purpose of these blog posts, we'll focus on CIM XML and python, as that tends to be one of the simplest environments to rapidly develop client side code.  If you're new to python, you might want to take a brief tangent to familiarize yourself with the basics at the python tutorial.

For the purposes of these examples, we're assuming you're running python on some remote management system which could be running Windows, Linux, MacOS, etc..  The very first thing you'll need to do once you have a python runtime on your local system, is install a CIM XML client library.  We'll be using pywbem for these examples.  Once you download pywbem, installing should be as simple as "python install"

To make sure everything's working, start python without any arguments, and you should see a prompt something like the following:

Python 2.6.4 (r264:75706, Dec  7 2009, 18:45:15) 
[GCC 4.4.1] on linux2
Type "help", "copyright", "credits" or "license" for more information.

Then try typing "import pywbem" and if that doesn't give an error, you're ready to start running CIM XML python scripts.

Python 2.6.4 (r264:75706, Dec  7 2009, 18:45:15) 
[GCC 4.4.1] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import pywbem

So now let's try writing our very first simple CIM client to print out the version of ESX the system is running.  VMware implements the DSP1023 – Software Inventory Profile for a number of different scenarios. Of particular interest for this example, we subclass the CIM_SoftwareIdentity class with a class called VMware_HypervisorSoftwareIdentity that reports the version of ESX the system is running.  We'll display just the VersionString property, but if you look at the API docs, you can see there are quite a few additional properties available.  When viewing the VMware API docs, we have added a VMware specific "qualifier" called ProviderImplemented that indicates if the class, property, or method is implemented by the system.  Since we're using the standard CIM schema, there are quite a few available properties, and not all of them are always implemented.  The properties that aren't implemented will always have a NULL or "None" (in python speak) value.  Here's a look at the code:

#!/usr/bin/env python

# First import the various python modules we'll need 
import pywbem
import os
import sys
from optparse import OptionParser
# Some command line argument parsing gorp to make the script a little more
# user friendly.
usage = '''Usage: %prog [options]

      This program will dump the version of ESX from a host specified with 
      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'
if options.username is None:
   options.username = 'root'
if options.password is None:
   options.password = ''

# Set up the client connection object.
# Hint – With CIM XML, there is no concept of statefull sessions
#        so this call doesn't actually connect to the server.  That
#        happens later once we send a request
client = pywbem.WBEMConnection('https://'+options.server,
                               (options.username, options.password),

# Now send an "Enumerate Instances" request.  This will fetch all
# instances of the specified classs (or subclasses)
list = client.EnumerateInstances('VMware_HypervisorSoftwareIdentity')
if list is None:
   print 'Error: Unable to locate any instances of
   # We know there's only once instance, so we can skip looping for now
   print list[0]['VersionString']

Python is finicky about white-space formatting, so just to make sure the code doesn't get corrupted, a complete copy of the script is attached for download.

In our next installment, we'll take a look at some of the SMBIOS based hardware asset information that's available on the system.