Managing VMware with CIM and PowerShell

In PowerShell 3.0, Microsoft introduced the Common Information Model (CIM) cmdlets as a way of working with WMI information. The advantage was that instead of connecting to WMI over RPC and DCOM, which is not very firewall-friendly, we can connect using the WSMan protocol, delivered by the WinRM service which uses only a couple ports. Here’s the best part and why you should be learning to how to use the CIM cmdlets: You can connect to any device or server that supports WSMan and CIM. This includes a VMware ESXi server.

Manage VMware with CIM: Connect to WSMan

What I’m going to demonstrate does not use any of the PowerCLI cmdlets. Instead, you can use existing CIM cmdlets in PowerShell 3.0. I will warn you up front that getting WMI information from a VMware server is not easy or obvious. Depending on your server and network configuration, your experience might be quite different and could entail a bit of research and a lot of trial and error.
To begin, I’m going to create a CIM session object to my ESXi server. Because my server does not use Active Directory for authentication, nor is it configured with an appropriate certificate, I’ll need to set some options for my CIM session.

​ PS C:\> $CIMOpt = New-CimSessionOption -SkipCACheck -SkipCNCheck -SkipRevocationCheck -Encoding Utf8 –UseSsl

If you can’t establish a CIM session outright, you might need to experiment with different options. Although I suspect at a minimum you will need to set encoding and use SSL.
To create my session, I will need to authenticate.

​ PS C:\> $HostUsername = Get-Credential root

Now to create my session.

​ PS C:\> $Session = New-CimSession -Authentication Basic -Credential $HostUsername -ComputerName "esx.jdhitsolutions.local" -port 443 -SessionOption $CIMOpt
PS C:\> $session
Id           : 2
Name         : CimSession2
InstanceId   : 645a6236-4f10-485a-89c3-4e2c01bda1ca
ComputerName : esx.jdhitsolutions.local
Protocol     : WSMAN

Unfortunately, you can’t use Test-WSMan with the VMware host.

CIM Classes

I’m assuming that when the VMware server was installed, nobody skipped the option to enable WMI and CIM support. If you did, then none of what I’m showing you will work. But assuming you are ready to go, all that remains is to query a class.
The default namespace is root/cimv2. However, enumerating classes is almost next to impossible using the existing CIM cmdlets. In fact, the only cmdlet that seems to work reliably well is Get-CimInstance. I think you will find it easiest to research the class names ahead of time, although I’ll demonstrate a few in a bit. The best place to start is in the vSphere documentation.
Even though you will see things like OMC and VMWare, these are extensions of the parent CIM classes, which from what I can tell are the only ones you can query using Get-CimInstance. It might be possible to get more granular using the winrm command-line tool, but that is going to be much more complicated. Be aware that even though you see a CIM class listed in the online documentation, there’s no guarantee you will get any instances of that class. Again, there is a lot of trial and error here.

Querying CIM

Using the established CIM session, querying the VMware server in some ways is not that much different than querying a Windows server.

​ PS C:\> $session | Get-CimInstance CIM_ComputerSystem

You can see my result in Figure 1.
Manage VMware with CIM
 
An important note: the class names are case-sensitive. Typically CIM_ and then the remainder in camel case. Use whatever format you see in the online documentation.
Querying this class actually results in two instances, which are the derived OMC classes.

​ PS C:\> $session | Get-CimInstance CIM_ComputerSystem | Select CreationClassName
CreationClassName
-----------------
OMC_ModularComputerSystem
OMC_UnitaryComputerSystem

You will see this behavior often.
Another useful query might be to get processor information.
Manage VMware with CIM processor information
Or Ethernet port.

​ PS C:\> $session | Get-CimInstance CIM_EthernetPort

Manage VMware with CIM ethernet port
You will find a number of elements bundled together by a parent CIM class, which is often the easiest way to gather information or at least discover class names that you can use for a more refined command.
Manage VMware with CIM

​ PS C:\> $le.name
System BIOS
VMware ESXi
VMware ESXi Alternate Boot Bank
EVAL
c015a0c5-b3a1-db11-8d9f-001a923ac60b
MAP
vmk0
vmk0
Cache memory
Cache memory
System Memory
20202020202020202020202036514630465A5159
20202020202020202020202036514630425A3858
Unknown
Unknown
vmnic0
VMware:HostPowerManagement
SoftwareInstallationService
VMware_KernelModuleService

Unfortunately, you can’t simply create a WMI filter. A command like this will fail.

​ PS C:\> $session | Get-CimInstance CIM_LogicalElement -filter "name = 'System BIOS'"

It seems your best bet for now is to get everything and then pipe to Where-Object.

​ PS C:\> $le | where {$_.name -eq 'System Bios'}

If you want to identify all managed elements, use a command like this:

​ PS C:\> $cms = Get-CimInstance -CimSession $Session -ClassName CIM_ManagedSystemElement

This should include everything that was part of CIM_LogicalElement. Then use PowerShell to get what you want. Here’s a slightly complicated example to retrieve software information from my ESXi server.

​ $cms | where name -eq 'vmware esxi' |
Select Name,VersionString,
@{Name="ReleaseDate";Expression={[System.Management.ManagementDateTimeConverter]::ToDateTime( $_.ReleaseDate)}},
@{Name="LastStartTime";Expression={[System.Management.ManagementDateTimeConverter]::ToDateTime( $_.LastStartTime)}},
@{Name="Uptime";Expression={(Get-Date) - [System.Management.ManagementDateTimeConverter]::ToDateTime( $_.LastStartTime)}},
PSComputername

The date values are still in the DMTF format, so I convert them to something easier to read and also calculate an uptime. When I execute this code in my PowerShell 3 session I get a result like this.

​ Name           : VMware ESXi
VersionString  : 5.1.0 build-799733
ReleaseDate    : 7/31/2012 8:00:00 PM
LastStartTime  : 10/30/2013 2:49:02 PM
Uptime         : 8.23:31:56.7340940
PSComputerName : esx.jdhitsolutions.local

Once you know what you want, it wouldn’t take that much more work to turn your command into easy to use PowerShell tools and functions.
The promise of one management tool for everything, regardless of platform, is very tantalizing. Learning how to manage your VMware servers with CIM and PowerShell would be a good place to start. Just be prepared for a lot of trial and error and experimentation, and if you have successes, I hope you‘ll share them with the community.