To some of you the second Tuesday of each month is just another day, but to the rest of us this day is known as "patch Tuesday". The second Tuesday of each month is when Microsoft releases security updates for it's products to the world. Our group previously had a patching process that worked like a charm for the majority of our boxes which were running W2K3 but now we have several WS08 RTM boxes in production as well. During the last patching cycle I had to rig up a less-than-elegant solution to patch those WS08 servers so I told myself that after the dust settled I'd look into a better way of handling it as well as consolidating the two processes.
After pondering how I would attack this issue I found that the Windows Update Agent API was a likely candidate to assist me. I fired up Visual Studio and set a reference to wuapi.dll then quickly threw together a proof-of-concept to show to the rest of my team. Below you will find the source necessary to query Windows Update, add packages to an install manifest, download said packages, and install the packages. Hopefully this will get you started if you are in fact looking for a custom Windows Update solution.
static void Main(string[] args)
{
StreamWriter hLogFileHandle = null;
hLogFileHandle = GetLogFileHandle(@"C:\sdmedic\logs\wuagent.log");
WriteToLogFile(hLogFileHandle, "Installation started by: " + Environment.UserName + Environment.NewLine);
WriteToLogFile(hLogFileHandle, DateTime.Now.ToString());
UpdateSessionClass oUpdateSession = new UpdateSessionClass();
UpdateSearcher oUpdateSearcher = (UpdateSearcher)oUpdateSession.CreateUpdateSearcher();
ISearchResult oSearchResult = oUpdateSearcher.Search("IsInstalled=0 and Type='Software'");
if (oSearchResult.Updates.Count > 0)
Console.WriteLine("Found " + oSearchResult.Updates.Count + " updates.");
WriteToLogFile(hLogFileHandle, "Found " + oSearchResult.Updates.Count + " updates.");
for (int iIndex = 0; iIndex < oSearchResult.Updates.Count; iIndex++)
//Console.WriteLine(oSearchResult.Updates[iIndex].Title);
}
UpdateCollectionClass oNeededUpdates = new UpdateCollectionClass();
IUpdate oUpdatePackage = oSearchResult.Updates[iIndex];
oNeededUpdates.Add(oUpdatePackage);
Console.WriteLine("Added " + oUpdatePackage.Title + " to download manifest.");
WriteToLogFile(hLogFileHandle, "Added " + oUpdatePackage.Title + " to download manifest.");
UpdateDownloader oDownloader = oUpdateSession.CreateUpdateDownloader();
oDownloader.Updates = oNeededUpdates;
Console.Write("Downloading updates...");
WriteToLogFile(hLogFileHandle, "Downloading updates...");
oDownloader.Download();
Console.WriteLine("done");
WriteToLogFile(hLogFileHandle, "done");
Console.WriteLine("Verifying downloaded updates...");
WriteToLogFile(hLogFileHandle, "Verifying downloaded updates...");
if (oUpdatePackage.IsDownloaded)
Console.Write("Verified " + oUpdatePackage.Title);
WriteToLogFile(hLogFileHandle, "Verified " + oUpdatePackage.Title);
Console.WriteLine("");
UpdateCollectionClass oUpdateManifest = new UpdateCollectionClass();
oUpdateManifest.Add(oUpdatePackage);
Console.WriteLine("Added " + oUpdatePackage.Title + " to install manifest.");
WriteToLogFile(hLogFileHandle, "Added " + oUpdatePackage.Title + " to install manifest.");
UpdateInstaller oInstaller = (UpdateInstaller)oUpdateSession.CreateUpdateInstaller();
oInstaller.Updates = oUpdateManifest;
Console.WriteLine("Installing...");
WriteToLogFile(hLogFileHandle, "Installing...");
IInstallationResult oInstallationResult = oInstaller.Install();
Console.WriteLine("Result: " + oInstallationResult.ResultCode.ToString());
WriteToLogFile(hLogFileHandle, "Result: " + oInstallationResult.ResultCode.ToString());
Console.WriteLine("Reboot: " + oInstallationResult.RebootRequired.ToString());
WriteToLogFile(hLogFileHandle, "Reboot: " + oInstallationResult.RebootRequired.ToString());
Console.WriteLine(oUpdateManifest[iIndex].Title + ": " + oInstallationResult.GetUpdateResult(iIndex).ResultCode.ToString());
WriteToLogFile(hLogFileHandle, oUpdateManifest[iIndex].Title + ": " + oInstallationResult.GetUpdateResult(iIndex).ResultCode.ToString());
Console.WriteLine(oUpdateManifest[iIndex].Title + ": " + oInstallationResult.GetUpdateResult(iIndex).RebootRequired.ToString());
WriteToLogFile(hLogFileHandle, oUpdateManifest[iIndex].Title + ": " + oInstallationResult.GetUpdateResult(iIndex).RebootRequired.ToString());
if (oInstallationResult.RebootRequired)
Console.WriteLine("Initiating system restart.");
WriteToLogFile(hLogFileHandle, "Initiating system restart.");
ExitWindows(ExitWindowsTypes.Reboot);
CloseLogFileHandle(hLogFileHandle);