How to Find Install Date of Windows Patch Delpoyed via BigFix

Hello,

We are tying to develop a custom analysis and/or report which tells us
the most recent date that a Microsoft Windows update was pushed to a
machine. This will be appended to a report that will include machine name, os, sp, etc. This report will mainly be used for reporting on compliance and auditing purposes.

Our issue is that the registry key LastSuccessTime found in the path
below does not update when a Microsoft Windows update is deployed via
BigFix:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpda te\Auto Update\Results\Install

Is there a specific place this information is logged when pushing a
Windows update via BigFix that we can use in order to generate a report
or analysis via BigFix? We would like to create this report easily for
all of the machines within our organization that reports to BigFix.

We also thought about using a custom report or analysis that would
report back the machine name, os, etc and the last time a specific
baseline was pushed to the machine. This would suffice if we are
unable to find the most recent date a MS Windows update was
installed. We typically create a new baseline each month with each
being named for the month. This would require us to have to enter the
name of the newest baseline each time a report was created.

We are looking for any suggestions that may help us with reporting in this way.

Thank You.

Hi jfred176,

I happen to have a solution, I don’t think it’s officially documented by MS though.

Examine under registry key HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\Packages, we will find the Packages of the Windows Patch you installed. We can search it by KB, for example: Package_for_KB3102810~31bf3856ad364e35~amd64~~6.1.1.2

Under this key there are two values, InstallTimeHigh and InstallTimeLow. These two values combine gives a large integer, which is a 18-digit LDAP/FILETIME timestamp.

Timestamp = InstallTimeHigh * 2^32 + InstallTimeLow

The LDAP/FILETIME timestamp is essentially “the number of 100-nanoseconds intervals (1 nanosecond = one billionth of a second) since Jan 1, 1601 UTC.” We can calculate and convert it to readable date. Here is an online tool: LDAP, Active Directory & Filetime Timestamp Converter

Hope the above helps. Note that this only works on Kernel patches (i.e. not for Microsoft Office patches for example).

1 Like

Double-check this for accuracy, but I think I’ve got the calculation worked out in relevance…

  q: maximum of ("1 Jan 1601 00:00:00 -0000" as time + it * second) of ((item 0 of it * 4294967296 + item 1 of it) / 10000000) of (values "InstallTimeHigh" of it as integer, values "InstallTimeLow" of it as integer) of keys whose (name of it starts with "Package_") of keys "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\Packages" of native registry
A: Tue, 13 Dec 2016 22:19:21 -0600
T: 75.787 ms
I: singular time

You should be able to use that in an Analysis property, but probably shouldn’t evaluate it more than once daily.

1 Like

:edit: Edited to use “unique values of…” to reduce duplicate results

Here’s an update for three properties I’ve put into an Analysis to use this:

Current Installed RollupFix

q: names of keys whose (name of it starts with "Package_for_RollupFix~" and (value "CurrentState" of it as integer is contained by set of (112;128))) of key "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\Packages" of native registry
A: Package_for_RollupFix~31bf3856ad364e35~amd64~~14393.1770.1.6
T: 78.690 ms
I: plural string

Installed Updates and Rollup Fix Versions

q: unique values of ((preceding text of first "~" of following text of first "for_" of it & " - " & following text of last "~" of it) of name of it) of (keys (unique values of names of values of keys "Owners" of keys whose (exists matches(regex("^Package_([\d]+_for_KB|for_RollupFix).*")) of name of it) of it) of it) of keys "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\Packages" of native registry
A: KB3186568 - 10.0.1.1044
A: KB3211320 - 10.0.1.1
A: KB4013418 - 10.0.1.0
A: KB4023834 - 10.0.1.0
A: KB4035631 - 10.0.1.0
A: KB4038806_RTM - 10.0.1.0
A: RollupFix - 14393.1770.1.6
A: RollupFix_Wrapper - 14393.1770.1.6
T: 231.656 ms
I: plural string with multiplicity

Installed Updates and Rollup Fix Versions - Installation Times

q: unique values of (((preceding text of first "~" of following text of first "for_" of it & " - " & following text of last "~" of it) of name of it) & " | " &  (("1 Jan 1601 00:00:00 -0000" as time + ((value "InstallTimeHigh" of it as integer * 4294967296 + value "InstallTimeLow" of it as integer) / 10000000 * second )) of it as string | "No install record")) of (keys (unique values of names of values of keys "Owners" of keys whose (exists matches(regex("^Package_([\d]+_for_KB|for_RollupFix).*")) of name of it) of it) of it) of keys "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\Packages" of native registry
A: KB3186568 - 10.0.1.1044 | Fri, 15 Sep 2017 19:03:15 -0500
A: KB3211320 - 10.0.1.1 | Wed, 15 Feb 2017 14:14:56 -0500
A: KB4013418 - 10.0.1.0 | Tue, 06 Jun 2017 13:08:40 -0500
A: KB4023834 - 10.0.1.0 | Fri, 14 Jul 2017 15:35:55 -0500
A: KB4035631 - 10.0.1.0 | Fri, 15 Sep 2017 19:03:23 -0500
A: KB4038806_RTM - 10.0.1.0 | Fri, 15 Sep 2017 19:03:15 -0500
A: RollupFix - 14393.1770.1.6 | Fri, 13 Oct 2017 20:42:48 -0500
A: RollupFix_Wrapper - 14393.1770.1.6 | Fri, 13 Oct 2017 20:42:48 -0500
T: 245.147 ms
I: plural string with multiplicity

The RollupFix versions correspond to OS Build Numbers described at the following links:

Windows 10 and Windows Server 2016 https://support.microsoft.com/en-us/help/4000825
Windows 8.1 and Windows Server 2012 R2 https://support.microsoft.com/en-us/help/4009470
Windows Server 2012 https://support.microsoft.com/en-us/help/4009471
Windows 7 SP1 and Windows Server 2008 R2 https://support.microsoft.com/en-us/help/4009469

1 Like

This is slow, but it is just (name, installtime) of everything:

( name of it, ("1 Jan 1601 00:00:00 -0000" as time + ((value "InstallTimeHigh" of it as integer * 4294967296 + value "InstallTimeLow" of it as integer) / 10000000 * second )) ) of keys whose(exists values "InstallTimeHigh" of it AND exists values "InstallTimeLow" of it) of keys "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\Packages" of (x64 registries; x32 registries)

I find that some my systems have thousands of extraneous of results that can be collapsed using my lookup of “Owners”.

For instance
Package_1_for_KB1234567~(blah)
Package_2_for_KB1234567~(blah)
…
Package_299_for_KB1234567~(blah)
Package_300_for_KB9876543~(blah)
Package_301_for_KB9876543

Each of these has an Owner value beneath it, which all reference the parent package (KB1234567 or KB9876543), so I collapse to fewer results by looking at those unique KB names.

Now that I think of it, there may be simpler form to consolidate the package list which I’ll try out tomorrow, but I think the effort is worth it. Aside from lookup time on the client, displaying so many results in the Console slows it considerably.

1 Like