I am trying to collect an accurate picture of Windows Updates, specifically KB installations, on a number of different machines. I've tried a number of different pieces of code that I've found scattered about, but I still cannot seem to create an accurate picture of what is installed. By accurate, I mean that whatever I gather seems to be a subset of what is shown when I check the Windows Update History on the machine using the Windows UI! Can't seem to figure this out!
Here are a few things I've tried;
UpdateSession uSession = new UpdateSession();
IUpdateSearcher uSearcher = uSession.CreateUpdateSearcher();
uSearcher.Online = false;
ISearchResult sResult = uSearcher.Search("IsInstalled=1");
foreach (IUpdate update in sResult.Updates)
{
foreach (string kbaid in update.KBArticleIDs)
{
txtAllUpdates.AppendText(kbaid + Environment.NewLine);
}
}
I also tried adding code within this same routine to gather all of the updates within the Bundled Updates field, like so;
foreach (IUpdate update2 in update.BundledUpdates)
{
txtAllUpdates.AppendText("\t--> " + update2.Title + Environment.NewLine);
foreach (string kbaid2 in update2.BundledUpdates)
{
string kbNo = GetKBNo(update2.Title.ToLower());
txtAllUpdates.AppendText("\t\t" + kbNo);
}
}
I also tried looking at the Update History, but that provided me with yet another set of data - still not complete!
UpdateSession updateSession = new UpdateSession();
IUpdateSearcher updateSearcher = updateSession.CreateUpdateSearcher();
int count = updateSearcher.GetTotalHistoryCount();
MessageBox.Show("Total Count = " + count);
IUpdateHistoryEntryCollection history = updateSearcher.QueryHistory(0, count);
for (int i = 0; i < count; ++i)
{
txtAllUpdates.AppendText("\t\t\t" + history[i].Title);
}
I also checked into some code that leverages the registry, but from what I've read, that's not the right way to do things. At this point, I'm performing a number of different queries, searching entries for "KB" references and building a list and removing duplicates, but I'm still not getting the same list I see on the screen! Even if this did work, it can't possibly be the right way to go - I feel like I must be missing something.
Finally, I tried to just get information on when updates were last checked for and installed - even that doesn't match up with what is displayed. I did this with the following code;
var auc = new AutomaticUpdatesClass();
DateTime? lastInstallationSuccessDateUtc = null;
if (auc.Results.LastInstallationSuccessDate is DateTime)
lastInstallationSuccessDateUtc = new DateTime(((DateTime)auc.Results.LastInstallationSuccessDate).Ticks, DateTimeKind.Utc);
DateTime? lastSearchSuccessDateUtc = null;
if (auc.Results.LastSearchSuccessDate is DateTime)
lastSearchSuccessDateUtc = new DateTime(((DateTime)auc.Results.LastSearchSuccessDate).Ticks, DateTimeKind.Utc);
lblInstall.Text += lastInstallationSuccessDateUtc.ToString();
lblSearch.Text += lastSearchSuccessDateUtc.ToString();
Does anyone have some expertise in this area? Really want to get this done right!
Thanks for taking the time to read!
Respectfully, Marshall
All the various ways to find installed software is incomplete, so I used a variety of ways in Get-KbInstalledUpdate, which I describe as a:
Though I haven't tried this way, which is essentially: