CIM_ or Win32_

If you dig into the classes available on a Windows machine you’ll see a mixture of prefixes – namely CIM_ and Win32_ used for the classes. So which should you use CIM_ or Win32_

Lets start by seeing whats available:

PS> Get-CimClass -ClassName *Volume*


    NameSpace: ROOT/CIMV2

CimClassName
------------
Win32_VolumeChangeEvent
Win32_VolumeQuota
Win32_VolumeQuotaSetting
Win32_VolumeUserQuota
CIM_StorageVolume
Win32_Volume
CIM_VolumeSet
Win32_ShadowVolumeSupport
CIM_LogicalDiskBasedOnVolumeSet
Win32_ShadowDiffVolumeSupport

The CIM_ classes follow the standard definition from the DMTF – https://www.dmtf.org/standards/cim

The Win32_ classes are Microsoft’s versions of the equivalent CIM_ class often with additional properties and methods.

I’ve always recommended using the Win32_ classes because they are “optimised” for Windows. The one exception that I’ve found is CIM_Datafile that doesn’t have a Win32_ equivalent.

A question on the forum asked why this was failing

PS> Get-CimInstance -ClassName CIM_StorageVolume -Filter "DriveLetter='C:'"

 Get-CimInstance : Invalid query
 At line:1 char:1
 + Get-CimInstance -ClassName CIM_StorageVolume -Filter "DriveLetter='C: ...
 + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     + CategoryInfo          : InvalidArgument: (:) [Get-CimInstance], CimException
     + FullyQualifiedErrorId : HRESULT 0x80041017,Microsoft.Management.Infrastructure.CimCmdlets.GetCimInstanceCommand

When this worked

PS> Get-CimInstance -ClassName CIM_StorageVolume | select Name, DriveLetter, Capacity

Name                                              DriveLetter     Capacity
----                                              -----------     --------
\\?\Volume{c1c4c5bb-0000-0000-0000-100000000000}\                366997504
C:\                                               C:          511210610688
\\?\Volume{c1c4c5bb-0000-0000-0000-801c77000000}\                529526784
D:\                                               D:

The reason is that you’re not getting back CIM_StorageVolume:

PS> Get-CimInstance -ClassName CIM_StorageVolume | Get-Member


    TypeName: Microsoft.Management.Infrastructure.CimInstance#root/cimv2/Win32_Volume

You’re getting Win32_Volume which DOES have a DriveLetter property. Get-WmiObject works in the same way. Looking at the properties:

PS> (Get-CimClass -ClassName CIM_StorageVolume ).CimClassProperties | Where Name -like "D*"

Name               : Description
Value              :
CimType            : String
Flags              : Property, ReadOnly, NullValue
Qualifiers         : {read}
ReferenceClassName :

Name               : DeviceID
Value              :
CimType            : String
Flags              : Property, ReadOnly, NullValue
Qualifiers         : {CIM_Key, read}
ReferenceClassName :

No DriveLetter. Now try Win32_Volume

PS> (Get-CimClass -ClassName Win32_Volume ).CimClassProperties | Where Name -like "D*"

Name               : Description
Value              :
CimType            : String
Flags              : Property, ReadOnly, NullValue
Qualifiers         : {read}
ReferenceClassName :

Name               : DeviceID
Value              :
CimType            : String
Flags              : Property, Key, ReadOnly, NullValue
Qualifiers         : {CIM_Key, read, key, MappingStrings...}
ReferenceClassName :

Name               : DirtyBitSet
Value              :
CimType            : Boolean
Flags              : Property, ReadOnly, NullValue
Qualifiers         : {read}
ReferenceClassName :

Name               : DriveLetter
Value              :
CimType            : String
Flags              : Property, NullValue
Qualifiers         : {read, write}
ReferenceClassName :

Name               : DriveType
Value              :
CimType            : UInt32
Flags              : Property, ReadOnly, NullValue
Qualifiers         : {MappingStrings, read}
ReferenceClassName :

Win32_Volume has 2 extra properties that start with the letter D, including DriveLetter. Win32_Volume is derived from, and builds on, CIM_StorageVolume

PS> Get-WmiObject -Class Win32_Volume | select -First 1 | select -ExpandProperty __Derivation

CIM_StorageVolume
CIM_StorageExtent
CIM_LogicalDevice
CIM_LogicalElement
CIM_ManagedSystemElement

If you want to get volume information on a Windows box use Win32_Volume or better still on Windows 8 and later use Get-Volume.

The only possible reason for using CIM_StorageVolume is that you’re learning more about CIM or you’re trying some cross-platform task. As I can’t think of a platform other than Windows that has implemented CIM_StorageVolume not sure how far you’ll get on the latter. If you do try CIM_StorageVolume you can filter using the Name property:

Get-CimInstance -ClassName CIM_StorageVolume -Filter "Name='C:\\'"

Note that you have to use C:\\ not C:\ because \ is an escape character in WQL.

Alternatively, use where-object to filter:

Get-CimInstance -ClassName CIM_StorageVolume | where DriveLetter -eq 'C:'

If you’re working remotely the first option is best as it reduces the amount of data being returned across the network.

If in doubt use the Win32_ class rather than the CIM class.

Advertisements
This entry was posted in PowerShell and CIM. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s