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.
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.
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.
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.
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.
Or Ethernet port.
PS C:> $session | Get-CimInstance CIM_EthernetPort
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.
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.