MSEndpointMgr

Hardware Inventory and extending Quick Fix Engineering in ConfigMgr

In the comments of one of my PowerBI posts recently someone brought up a question about how do we tell if and when a patch was installed. This prompted me to start working on this post and talk about not only how to enable collection of the quick fix engineering information but why you should or shouldn’t do it and when it is or isn’t useful.

What is Quick Fix Engineering?

Before we get into doing anything with the hardware inventory or ConfigMgr I want to talk about what is Quick Fix engineering and why should or shouldn’t care about it. Quick Fix Engineering, QFE for short, is a WMI class known as WIN32_QuickFixEngineering. The purpose of this class is to track the Microsoft hotfix’s that have been applied to your device. However, with the advent of Windows 10 and the Windows as a Service (WaaS) model, the information that is returned has changed drastically. Historically one could run open Powershell and run the following PowerShell command and get ALL of the updates that are installed on a device:

Get-hotfix -ComputerName 'SomePCHere'

While this is is still true it’s not the case with devices that are in the WaaS model in fact devices in the WaaS model specifically newer Windows 10 machines are only going to show the most recent bundle of updates. To give an example here are the results of get-hotfix from my machine which I update every month.

Notice how there is only one update from earlier this year and that update was a strange one-off security update I manually applied? This should be similar on all Windows 10 devices.

However, if we run the same query on a 2012R2 server or a Windows 7 device we’ll get something that could be construed as much more useful:

At the end of the day, the QFE class is a WMI class that depending on your operating system will store important information about what hotfixes are currently installed.

OK So I know what it is but should I actually do anything with it? 

This is a tricky question and I think it depends on what you are looking for and how modern your environment is. In the long run, I think the information in QFE is slowly going the way of the dodo bird. Sure I can think of some very specific use cases for it especially if your environment is still heavily invested in Windows 7 or if you want a second point of validation ‘Compliance’ data generated by WSUS. I’m going to show you how to enable collection of QFE data within ConfigMgr however, I encourage you to review and answer the following questions before extending hardware inventory:

  1. What percentage of your environment is on Windows 10 and Server 2016? The more devices on 10 and 2016 the less information will be returned from a ‘historic’ perspective.
  2. What specifically are you trying to get out of the QFE information?
    1. Most Recently Installed HotfixID and the date -> Is this because you don’t trust WSUS data for compliance or are you looking for more of a True/False statement?
    2. Installed By -> are you attempting to audit is someone manually patching things or is ConfigMgr doing it?
    3. Are you just looking for concrete proof of the last CU that was installed?
  3. Is the volume of data you are going to add to your environment by enabling this feature, worth enabling it based on the above questions and answers?

I answered your questions bridgekeeper now show me the way!

So by now, we’ve learned what QFE is and a little bit in how it’s relevant. It’s useful in telling us the patches that were installed historically for older operating systems, and the most recent installed CU for newer operating systems and while that data can also be gathered or assumed from update compliance information in WSUS this information is a little more True/False.

First lets take a look and see if we have QFE collection turned on anywhere in the environment. We can do this a couple of ways I’m a big fan of SQL and a quick query will answer this:

select * from V_GS_Quick_Fix_Engineering

If you run the above and get the following, you’re not currently collecting any QFE data.

For my example, we are going to pop open the ConfigMgr console go to ‘Administration’ expand ‘Overview’ and select Client settings.

From the ribbon we are going to create a new Custom Client Device Setting I would suggest doing this for testing, but if you implement in production role this setting up with your existing hardware inventory settings.

This will open up the friendly neighborhood ‘Create Custom Client Device Settings’ dialogue box. From here we will want to name our policy, add a description, then select ‘Hardware Inventory’ as that’s what we are going to make a change to and then select ‘Hardware Inventory’ on the left-hand side so we can edit what exactly hardware inventory is doing.

Once we select Hardware inventory we will need to do a little configuration. I personally like hardware inventory to happen a little more aggressively than once every seven days. I actually have mine occur once every 24 hours so the first thing I’m going to do is select ‘Schedule’ and change it to occur every day.

Then I’m going to select Set classes from the previous image and in the search bar enter ‘Quick’ to filter down all the available WMI classes.

Now before we go any further I want to take a moment to examine the contents of what exactly we are turning on and you’ll notice something interesting. If you’ve ever run ‘Get-hotfix’ before you’ve probably noticed this is way more data than what comes back as a result. In fact, even if you run Get-WMIobject or Get-CimInstance its STILL more information than what comes back. A little digging with WBEMTEST or your preferred WMI explorer will reveal why. The information technically not a part of the class but is referenced from that class and can be selected by adding the explicit property to the selection. In the event you don’t, believe me, you can prove this out by:

When you click connect you’ll get the following:

You will then want to select ‘Enum Instances’

And enter the superclass name ‘Win32_QuickFixEngineering’

Select one of the options and double click it, do not click the add or delete buttons.

This will load the object editor for the specific KB and you can see that the ‘Caption’ field if you double click on it is related to an entirely different object.

Returning from our detour for our example I’m only going to select the information that I care about:

You can then hit OK on this, and OK on the client settings. And then deploy them to a collection by right-clicking the client setting, select deploy and then choose the collection you would like to depoy too.

You can then wait for a client to check in, or use client notification to force the test machine to download policy and then collect hardware inventory. As you can see the information for my CAS has already come back:

Now that you’ve started collecting this information you can use it for collecting specific HotfixID’s just be aware of the limitations of the data as well as the upsides in reporting. This table can be joined to other tables using the ResourceID column.

Jordan Benzing

Jordan has been working in the Industry since 2009. Since starting he’s worked with Active Directory, Group Policy, SCCM, SCOM and PowerShell. Jordan most recently worked in the healthcare industry as an SCCM Infrastructure Team lead supporting over 150,000 endpoints. Jordan currently works as a Senior consultant for TrueSec Inc in the U.S. Most recently his focus has been in SQL Reporting for SCCM, creation of PowerShell scripts to automate tasks and PowerBI.

15 comments

  • You note that this is only useful for determining historical data on older OS’s. For newer Windows 10 devices, is there an alternative in seeing data for installed updates?

    • Thanks! You caught the typo. I’ve fixed it in the earlier lines. The funny part is I clearly used the correct spelling later on in the post when I screenshot the results.

      oops.

      • No worries! It was actually IntelliSense that caught it, not me. Great writeup, btw. This is instrumental in cutting through all 600 of the Updates tables to get clear data re: patching.

        One helpful thing with this table was a join as a sub-select, to grab the “last installed patch” date, ie:

        select * from v_r_system sms

        join (select resourceid, max(cast(installedon0 as datetime)) as installedon0
        from v_GS_QUICK_FIX_ENGINEERING
        group by resourceid) as qfe on qfe.resourceid=sms.resourceid

        Hope this helps other admins.

  • I try to execute this scenario, but the result is no rows
    update published by WSUS not SCCM

    • It shouldn’t master who is publishing the updates to collect the QFE information however you won’t have anything to join in the UpdateInfo table because that information is populated by having the SUP information synced. That might be what you’re running into.

  • Hi Jordan,

    I tried to test this. It gives information related to only OS patches. Is there a way to get information of all patches installed like office and others.

    Regards,

    • Good Morning!

      Unfortunately with QFE the only things you get are what Microsoft Stamps to WMI in the Quick Fix Engineering class. In order to get the other types of updates you would have to find where those are stored and import those using the same steps as listed in the guide. I’m not sure if or where office updates get stamped to in WMI. I might take a look and see what I can find later on.

      Cheers!

      -J

  • Something of note, the time stamp always points to midnight. We know that the patches get deployed around the clock, why is “installed on” coming back as the same timestamp? Is there a way to get a true reading to DB for reporting?

    • Unfortunately none I am aware of. That information is stamped in WMI when the patch is installed and is always set to midnight of the day it was installed. That’s not to say you couldn’t get more accurate information if you were to go looking for a more specific WMI class and collect it but the information stored in QFE is set the way Microsoft Set it.

  • really awsome Jordan !
    I’ve been playing with both the options that you’ve suggested in your previous posts.
    But this really gives a better understanding about the “quick fix engineering” class.

    • Glad you liked it! Hope it helped provide some additional context to your previous question!

  • Great post, as usual!

    One question: what is the difference between “Installed on” and “InstallDate”? Do these not return the same data (when an update was installed) or am I misunderstanding something?

    • Ther is a difference actually! the ‘InstallDate’ object is a member of the CIM_ManagedSystemElement class. This class is a little different and because of how updates install and interact with WMI they don’t update information there. You can read more about the CIM_ManagedSystemElement class here: https://msdn.microsoft.com/en-us/library/aa387898(v=vs.85).aspx

Sponsors