Group policy filtering of installed applications

Hello AskPerf. This is Mick Bailey from the Performance team in Texas. I’ve had another customer case inspire a blog post. I hope this information will help some of you out there that are using group policy filtering as described below.

The specific case that I was involved in was one in which a customer’s users complained of slow logon times when they were connecting to Citrix servers in their environment. During instances of this symptom the administrators noted high CPU utilization on the Citrix servers associated with the Wmiprvse.exe process.

The Directory Services team actually started out with this case, since they support the logon process. To find out what was happening during the logon process the engineer had enabled USERENV logging. From the USERENV log, the Directory Services engineer had determined that the delays were associated with the process of applying policies. They also learned from the customer that group policy filtering was being utilized in the environment.

Once it was determined that the logon delays were associated with applying policies, and that group policy filtering was being implemented, and that high CPU was being noted in Wmiprvse.exe, I was engaged, since the Performance Team supports the WMI Service. I then learned that the customer was using a WMI group policy filter that queried the Win32_Product class. This class is used to gather information about applications that have been installed on a machine via Windows Installer packages.

Once I learned which class was being utilized I performed a quick query against it using the WMI testing utility Wbemtest.exe. When I executed the query I noted a similar type of delay that was being noted during logon. This told me that the issue had nothing to do with the group policy and/or the filter the customer was using. After some internal research I learned that the design of the provider for this class causes instances of Windows Installer service to be initiated when it is used to gather information via WMI about installed application packages. This process takes time and is what causes the noted delays. This article outlines the issue from another perspective.

To workaround this issue I suggested a different method to gather information about applications that are installed on a machine. This method utilizes entries within the Windows registry and more importantly and to the point of this blog is that it is much faster than using the Win32_Product class method. Applications that install via Windows Installer as well as some that don’t place information about themselves in the following Registry location:


This alternative method can be implemented in one of two ways. If the machines involved have the SMS/SCCM client installed there is a class created for the purposes of hardware inventory that uses the default WMI Registry provider to pull data from the above mentioned location. This class is Win32Reg_AddRemovePrograms and is under the root\cimv2 WMI namespace. This class can be used in a query such as this example where a specific version of NVIDIA DRIVERS is utilized as a filter:

Select * from Win32Reg_AddRemovePrograms where displayname = "nvidia drivers" AND version = "1.10"

For machines that don’t have the SMS/SCCM client installed then the second option is to create a WMI .mof file that can be compiled using Mofcomp.exe to establish a custom class that uses the WMI Registry provider to access the same location that the SMS/SCCM-related Win32Reg_AddRemovePrograms class does. The following TechNet topic discusses this concept:

How do I list all the installed applications on a given machine?

Here’s an example of the contents for a mof file that creates a class named Products under the root\cimv2 namespace:

#pragma autorecover
qualifier dynamic:ToInstance;
qualifier ProviderClsid:ToInstance;
qualifier ClassContext:ToInstance;
qualifier propertycontext:ToInstance;
[dynamic, provider("RegProv"),
class Products {
   [key] string KeyName;
   [read, propertycontext("DisplayName")]      string DisplayName;
   [read, propertycontext("DisplayVersion")]      string  DisplayVersion;
   [read, propertycontext("InstallLocation")]      string InstallLocation;

Compiling the above mof example would allow queries similar to the one I mentioned in the example above. So, if you are using WMI Filtering using the Win32_Product class and are experiencing slow logons, give this a shot.

Until next time..


Share this post :