Comparing CIM and WMI in PowerShell


Summary: Microsoft Scripting Guy, Ed Wilson, talks about comparing CIM and Windows PowerShell.

Hey, Scripting Guy! Question Hey, Scripting Guy! When I query using a CIM function, I get back different stuff than when I query WMI. I don’t get it. Can you help?

—BW

Hey, Scripting Guy! Answer Hello BW,

Microsoft Scripting Guy, Ed Wilson, is here. Yesterday in Working with Volumes in CIM, I began talking about WMI and CIM. Let’s continue by looking more in depth at what happens with Get-Volume and Win32_Volume.

Anyone who has done a lot of work with WMI and with Windows PowerShell knows about types and type data. For example, when I query the WIN32_BIOS WMI class, only a certain amount of information returns. This is shown here:

PS C:> Get-WmiObject win32_Bios

SMBIOSBIOSVersion : Hyper-V UEFI Release v1.0

Manufacturer      : Microsoft Corporation

Name              : Hyper-V UEFI Release v1.0

SerialNumber      : 6591-2614-0518-3297-7423-5669-65

Version           : VRTUAL - 1

If I want to look at more in-depth information, I can pipe the output to the Format-List cmdlet, and it will return all of the information, as shown here:

PS C:> Get-WmiObject win32_Bios | fl *

PSComputerName        : C1

Status                : OK

Name                  : Hyper-V UEFI Release v1.0

Caption               : Hyper-V UEFI Release v1.0

SMBIOSPresent         : True

__GENUS               : 2

__CLASS               : Win32_BIOS

__SUPERCLASS          : CIM_BIOSElement

__DYNASTY             : CIM_ManagedSystemElement

__RELPATH             : Win32_BIOS.Name="Hyper-V UEFI Release

                                   v1.0",SoftwareElementID="Hyper-V UEFI Release v1.0",
                                  SoftwareElementState=3,TargetOperatingSystem=0,Version="VRTUAL - 1"

__PROPERTY_COUNT      : 27

__DERIVATION          : {CIM_BIOSElement, CIM_SoftwareElement, CIM_LogicalElement, CIM_ManagedSystemElement}

__SERVER              : C1

__NAMESPACE           : rootcimv2

__PATH                : \C1rootcimv2:Win32_BIOS.Name="Hyper-V UEFI Release
      
                                v1.0",SoftwareElementID="Hyper-V UEFI Release v1.0",

                                 SoftwareElementState=3,TargetOperatingSystem=0,Version="VRTUAL - 1"

BiosCharacteristics   : {3, 9, 15, 16...}

BIOSVersion           : {VRTUAL - 1, Hyper-V UEFI Release v1.0, EDK II - 10000}

BuildNumber           :

CodeSet               :

CurrentLanguage       :

Description           : Hyper-V UEFI Release v1.0

IdentificationCode    :

InstallableLanguages  :

InstallDate           :

LanguageEdition       :

ListOfLanguages       :

Manufacturer          : Microsoft Corporation

OtherTargetOS         :

PrimaryBIOS           : True

ReleaseDate           : 20121126000000.000000+000

SerialNumber          : 6591-2614-0518-3297-7423-5669-65

SMBIOSBIOSVersion     : Hyper-V UEFI Release v1.0

SMBIOSMajorVersion    : 2

SMBIOSMinorVersion    : 4

SoftwareElementID     : Hyper-V UEFI Release v1.0

SoftwareElementState  : 3

TargetOperatingSystem : 0

Version               : VRTUAL - 1

Scope                 : System.Management.ManagementScope

Path                  : \C1rootcimv2:Win32_BIOS.Name="Hyper-V UEFI Release

                        v1.0",SoftwareElementID="Hyper-V UEFI Release v1.0",
                        SoftwareElementState=3,TargetOperatingSystem=0,Version="VRTUAL - 1"

Options               : System.Management.ObjectGetOptions

ClassPath             : \C1rootcimv2:Win32_BIOS

Properties            : {BiosCharacteristics, BIOSVersion, BuildNumber, Caption...}

SystemProperties      : {__GENUS, __CLASS, __SUPERCLASS, __DYNASTY...}

Qualifiers            : {dynamic, Locale, provider, UUID}

Site                  :

Container             :

The default properties that are displayed are the result of type data for the specific WMI class. I can find this by using the Get-TypeData cmdlet. Here is an example that tells me that I do, in fact, have specific type data for the WMI class:

PS C:> "*win32_bios*" | Get-TypeData

TypeName                                Members                                

--------                                -------                               

System.Management.ManagementObject#r... {}                                    

Microsoft.Management.Infrastructure.... {}              

I can look at this in more detail, by piping the results to the Format-List cmdlet:

S C:> "*win32_bios*" | Get-TypeData | fl * 

TypeName                        : System.Management.ManagementObject#rootcimv2 Win32_BIOS

Members                         : {}

TypeConverter                   :

TypeAdapter                     :

IsOverride                      : False

SerializationMethod             :

TargetTypeForDeserialization    :

SerializationDepth              : 0

DefaultDisplayProperty          :

InheritPropertySerializationSet : False

StringSerializationSource       :

DefaultDisplayPropertySet       : System.Management.Automation.Runspaces.PropertySetData

DefaultKeyPropertySet           :

PropertySerializationSet        : 

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

Members                         : {}

TypeConverter                   :

TypeAdapter                     :

IsOverride                      : False

SerializationMethod             :

TargetTypeForDeserialization    :

SerializationDepth              : 0

DefaultDisplayProperty          :

InheritPropertySerializationSet : False

StringSerializationSource       :

DefaultDisplayPropertySet       : System.Management.Automation.Runspaces.PropertySetData

DefaultKeyPropertySet           :

PropertySerializationSet        : 

But, what I really want to look at is DefaultDisplayPropertySet. This property is what governs the properties that return by default when I query the Win32_Bios cmdlet. So, I look at the property:

PS C:> ("*win32_bios*" | Get-TypeData).defaultdisplaypropertyset

ReferencedProperties                                                          

--------------------                                                          

{SMBIOSBIOSVersion, Manufacturer, Name, SerialNumber...}                      

{SMBIOSBIOSVersion, Manufacturer, Name, SerialNumber...}     

It is one more level to get the ReferencedProperties. This is shown here:

PS C:> ("*win32_bios*" | Get-TypeData).defaultdisplaypropertyset.referencedproperties

SMBIOSBIOSVersion

Manufacturer

Name

SerialNumber

Version

SMBIOSBIOSVersion

Manufacturer

Name

SerialNumber

Version

If you look closely, you will see that there are two sets of the same five properties. This is because I have two instances of type data. One is for WMI the other is for CIM.

PS C:> ("*win32_bios*" | Get-TypeData).typename

System.Management.ManagementObject#rootcimv2Win32_BIOS

Microsoft.Management.Infrastructure.CimInstance#root/cimv2/Win32_BIOS

At the beginning of this post, I used Get-WMIObject to query Win32_Bios. As shown here, if I use Get-CimInstance, the output is the same:

PS C:> Get-CimInstance Win32_BIOS

SMBIOSBIOSVersion : Hyper-V UEFI Release v1.0

Manufacturer      : Microsoft Corporation

Name              : Hyper-V UEFI Release v1.0

SerialNumber      : 6591-2614-0518-3297-7423-5669-65

Version           : VRTUAL - 1

What about Win32_Volume and Get-Volume? Well, we have a completely different WMI namespace. I can discover this by looking at the TypeName from Get-Member:

PS C:> Get-Volume | gm

   TypeName: Microsoft.Management.Infrastructure.CimInstance#ROOT/Microsoft/Win

dows/Storage/MSFT_Volume

Name                      MemberType     Definition                            

----                      ----------     ----------                           

Clone                     Method         System.Object ICloneable.Clone()     

Dispose                   Method         void Dispose(), void IDisposable.Di...

Equals                    Method         bool Equals(System.Object obj)       

GetCimSessionComputerName Method         string GetCimSessionComputerName()   

GetCimSessionInstanceId   Method         guid GetCimSessionInstanceId()       

GetHashCode               Method         int GetHashCode()                    

GetObjectData             Method         void GetObjectData(System.Runtime.S...

GetType                   Method         type GetType()                       

ToString                  Method         string ToString()                    

DriveLetter               Property       char DriveLetter {get;}              

FileSystem                Property       string FileSystem {get;}             

FileSystemLabel           Property       string FileSystemLabel {get;set;}    

ObjectId                  Property       string ObjectId {get;}               

Path                      Property       string Path {get;}                   

PSComputerName            Property       string PSComputerName {get;}         

Size                      Property       uint64 Size {get;}                   

SizeRemaining             Property       uint64 SizeRemaining {get;}          

DriveType                 ScriptProperty System.Object DriveType {get=switch...

HealthStatus              ScriptProperty System.Object HealthStatus {get=swi...

Notice, that the TypeName is a CimInstance, like one of the types for the Win32_Bios class. But notice that this also is in Root/Microsoft/Windows/Storage WMI namespace. This namespace is why Win32_Volume does not work on a computer running Windows 7, even though it may have Windows PowerShell 4.0 installed.

If I look for type data related to *volume*, I find four different types—but only one that is related to MSFT_Volume and none related to Win32_Volume. This is shown here:

PS C:> ("*volume*" | Get-TypeData).TypeName

System.Management.ManagementObject#rootcimv2Win32_VolumeQuotaSetting

Microsoft.Management.Infrastructure.CimInstance#root/cimv2/Win32_VolumeQuotaSetting

Microsoft.Management.Infrastructure.CimInstance#MSFT_Volume

Microsoft.FailoverClusters.PowerShell.ClusterSharedVolume

When I query Get-Volume, I get a nice clean output:

PS C:> Get-Volume

DriveLetter FileSystemLabel FileSystem  DriveType  HealthStatus SizeRemaining  Size

----------- ----------- ----------  ---------  ---------- ----------       ----

C                       NTFS        Fixed      Healthy     108.53 GB  126.48 GB

E           NEW VOLUME  FAT32       Fixed      Healthy       1.52 GB    1.99 GB

            Recovery    NTFS        Fixed      Healthy      59.83 MB     300 MB

D                                   CD-ROM     Healthy           0 B        0 B

But, if I query Win32_Volume, I get back the WMI class, but not any formatted data. This is true even if I use Get-CimInstance. This is shown here:

PS C:> Get-CimInstance win32_volume

Caption                      : C:

Description                  :

InstallDate                  :

Name                         : C:

Status                       :

Availability                 :

ConfigManagerErrorCode       :

ConfigManagerUserConfig      :

CreationClassName            :

DeviceID                     : \?Volume{a6325fa1-0f39-432c-a6db-e6388000463a}

ErrorCleared                 :

ErrorDescription             :

LastErrorCode                :

PNPDeviceID                  :

PowerManagementCapabilities  :

PowerManagementSupported     :

StatusInfo                   :

SystemCreationClassName      :

SystemName                   : C1

Access                       :

BlockSize                    : 4096

ErrorMethodology             :

NumberOfBlocks               :

Purpose                      :

Automount                    : True

BootVolume                   : True

Capacity                     : 135810510848

Compressed          &nb

Comments (1)

Skip to main content