21

A list of every update and hotfix that has been installed on my computer, coming from either Microsoft Windows Update or from the knowledge base. I need the ID of each in the form of KBxxxxxx or some similar representation...

Currently I have:

const string query = "SELECT HotFixID FROM Win32_QuickFixEngineering";
var search = new ManagementObjectSearcher(query);
var collection = search.Get();

foreach (ManagementObject quickFix in collection)
    Console.WriteLine(quickFix["HotFixID"].ToString());

But this does not seem to list everything, it only lists QFE's.

I need it to work on Windows XP, Vista and 7.

Tamara Wijsman
  • 12,198
  • 8
  • 53
  • 82

5 Answers5

14

After some further search on what I've found earlier. (Yes, the same as VolkerK suggests first)

  1. Under VS2008 CMD in %SystemRoot%\System32\ run a command to get a managed dll:
    tlbimp.exe wuapi.dll /out=WUApiInterop.dll
  2. Add WUApiInterop.dll as a project reference so we see the functions.

Using the following code I can get a list from which I can extract the KB numbers:

var updateSession = new UpdateSession();
var updateSearcher = updateSession.CreateUpdateSearcher();
var count = updateSearcher.GetTotalHistoryCount();
var history = updateSearcher.QueryHistory(0, count);

for (int i = 0; i < count; ++i)
    Console.WriteLine(history[i].Title);
Tamara Wijsman
  • 12,198
  • 8
  • 53
  • 82
  • 1
    No idea, I think that it would reflect the history as seen in Windows Update; but might be wrong, I suggest you to prototype it and see what it does. I currently don't have a Windows computer available, given that I'm running Gentoo Linux now. – Tamara Wijsman Mar 22 '14 at 14:24
  • How can I create an instance of `UpdateSession` on a remote machine? – Mark Richman May 02 '16 at 17:57
  • 1
    Today, on windows 10 Professional after installing windows update [KB3156421, KB890830 and KB3157993] (I guess KB3156421 is the problem); querying history[i].ResultCode throws a comException: Exception from HRESULT: 0x80240FFF, I have added a try/catch for this – buildcomplete May 11 '16 at 19:47
  • @buildcomplete: Seems more like a WSUS issue, consult https://blogs.technet.microsoft.com/sus/2011/04/14/new-kb-windows-update-may-encounter-error-0x80240fff-when-updates-published-on-an-internal-server-have-the-same-product-name-and-category-name/ for more information – Tamara Wijsman May 11 '16 at 23:19
  • @TomWijsman: I must admit, I don't know much about windows update etc, but: 1) The installed update are all installed by windows update automatically, we have no internal server installing updated. 2) we have only installed 'one' program on one of the machines failing (the program that was failing). 3) I can query some of the objects, it only fails after reading a number of them. – buildcomplete May 12 '16 at 08:40
  • It appears after running a local Windows 10 test, that the TotalHistoryCount report is wrong, as I get 1636 updates in count, but only 377 non-null entries (52 unique KBs) when I go through them. The null entries fail with the error on ResultCode even though UnmappedResultCode returns 0; I think you just need to test Title and skip the entry if it is null. – NetMage Oct 27 '16 at 21:07
10

You can use IUpdateSession3::QueryHistory Method.
The properties of the returned entries are described at http://msdn.microsoft.com/en-us/library/aa386400(VS.85).aspx

Set updateSearch = CreateObject("Microsoft.Update.Session").CreateUpdateSearcher
Set updateHistory = updateSearch.QueryHistory(1, updateSearch.GetTotalHistoryCount)

For Each updateEntry in updateHistory
  Wscript.Echo "Title: " & updateEntry.Title
  Wscript.Echo "application ID: " & updateEntry.ClientApplicationID
  Wscript.Echo " --"
Next

edit: also take a look at http://msdn.microsoft.com/en-us/library/aa387287%28VS.85%29.aspx

VolkerK
  • 95,432
  • 20
  • 163
  • 226
1
const string querys = "SELECT HotFixID FROM Win32_QuickFixEngineering";
var search = new ManagementObjectSearcher(querys);
var collection = search.Get();

foreach (ManagementObject quickfix in collection)
{
    hotfix = quickfix["HotFixID"].ToString();
}

listBox1.Items.Add(hotfix);

This will populate the listbox with currently installed Hotfixes or Updates

If you want to list all history of updates and hotfixes to show then, the above example of Tom Wijsman as stated will work

MikeH
  • 4,242
  • 1
  • 17
  • 32
0

Just in case you just want the list of updates and don't care if you get it via code or a GUI, here is how to do it in Powershell:

  1. Open PowerShell (preferably "run as admin")
  2. Type "get-hotfix" and hit enter. That's it.

Get hotfixes

Stein Åsmul
  • 39,960
  • 25
  • 91
  • 164
0
        string ExtractString(string s)
    {
        // You should check for errors in real-world code, omitted for brevity
        try
        {
            var startTag = "(";
            int startIndex = s.IndexOf(startTag) + startTag.Length;
            int endIndex = s.IndexOf(")", startIndex);
            return s.Substring(startIndex, endIndex - startIndex);
        }
        catch
        {
            return ("CNVFL");
        }
    }

Above is a simple extract string method I use to find that KB is in the security package like Tom Wijsman had mentioned and run his.

var updateSession = new UpdateSession();
var updateSearcher = updateSession.CreateUpdateSearcher();
var count = updateSearcher.GetTotalHistoryCount();
var history = updateSearcher.QueryHistory(0, count);

for (int i = 0; i < count; ++i){
   //sets KB here!!
   string _splitstring = ExtractString(history[i].Title);
   Console.WriteLine(_splitstring);
}

this would get you the KB number like you're looking for I believe