Enumerating and getting WMI provider class instances with performance in mind

 

Performance of CIM_DataFile and Win32_Directory enumeration depends on the number of files or directories that are being enumerated, and, hence, can be very slow and can take hours.

In following example, we run the Get-CimInstance cmdlet to enumerate all the instances of the class CIM_DataFile. On a brand-new virtual machine, the operation took 38minutes.

PS:> Measure-Command { Get-CimInstance -ClassName CIM_DataFile -Namespace root/cimv2 } Days : 0 Hours : 0 Minutes : 38 Seconds : 27

 

How performance can be improved

Here are few alternatives that can improve performance of your PowerShell script if it includes CIM_DataFile or Win32_Directory instanceenumeration. These methods can be used on any other class with a large number of instances.

 

Alternative 1: Enumerating instances using a WQL query

You can use a WQL query to narrow down enumeration to single instances. When you use WQL query, the Get-CimInstance cmdlet executes faster.

For example, the following query returns result immediately:

PS:> # Build a WQL query, which will return C:\ directory PS:> $query = "Select * From Win32_Directory Where Name = 'C:'" PS:> # Get Win32_Directory instance using WQL query PS:> $instances = Get-CimInstance -Query $query -Namespace root/cimv2 PS:> $instances | Select Name Name : c:

If WQL query uses the LIKE operator, expect the query to be as slow as Get-CimInstance without a WQL query.

PS:> # Build a WQL query, which will return all directories under C:\ PS:> $query = "Select * From Win32_Directory Where Name LIKE 'C:*'" PS:> # Get Win32_Directory instances matching the query filter PS:> Measure-Command { $instances = Get-CimInstance -Query $query -Namespace root/cimv2 } Days : 0 Hours : 0 Minutes : 2 Seconds : 34

 

 

Alternative 2: Enumerating instances using Get-CimInstance with local instance

This method can only be used when the instance key property value is known.

PS:> # Get CIM_DataFile class PS:> $class = Get-CimClass -ClassName CIM_DataFile -Namespace root/cimv2 PS:> # Create hash table containing instance’s key property and its value PS:> $keyPropertyHash = @{} PS:> $keyPropertyHash.Add('Name', 'C:\Temp\Test.txt') PS:> # Create a new CIM instance in memory for a CIM_DataFile class with the key property @{ 'Name'='C:\Temp\Test.txt' } PS:> $localInstance = New-CimInstance -CimClass $class -Property $keyPropertyHash –ClientOnly PS:> #Get Test.txt file instance using $localInstance as an input object PS:> $instance = Get-CimInstance –InputObject $localInstance PS:> $instance | fl Name Name : c:\temp\test.txt

 

Summary

When you’re enumerating instances in a class with large number of instances:

  • Use WQL queries if enumeration can be scoped down.
  • Run Get-CimInstance with the local instance if the key property value is known.
  • Avoid using queries with the LIKE operator if possible.
  • If you need full enumeration, plan for the time overhead that’s added to your script.

 

Link to related post:

Files and Folders

 

Thanks,

Milena Natanov [MSFT]

Standards-Based Management