17

Is there any API for writing a C# program that could interface with Windows update, and use it to selectively install certain updates?

I'm thinking somewhere along the lines of storing a list in a central repository of approved updates. Then the client side applications (which would have to be installed once) would interface with Windows Update to determine what updates are available, then install the ones that are on the approved list. That way the updates are still applied automatically from a client-side perspective, but I can select which updates are being applied.

This is not my role in the company by the way, I was really just wondering if there is an API for windows update and how to use it.

DevinB
  • 8,231
  • 9
  • 44
  • 54
  • You are surely looking for the Windows Update Agent API: http://msdn.microsoft.com/en-us/library/aa387099.aspx – Russ Bradberry May 28 '09 at 17:25
  • That's a COM interface oriented towards C and C++, so unless you wanted to give me a tutorial on how to call COM APIs from C#, it doesn't help me =(. Although, I'll be the first to admit that this is a failing of my knowledge, and not of your answer. – DevinB May 28 '09 at 17:35
  • I am not aware of any C# API. But have you consider [Windows Server Update Service](http://technet.microsoft.com/en-us/wsus/default.aspx) to help you manage Windows Update for enterprise level? – Adrian Godong May 28 '09 at 17:25

4 Answers4

24

Add a Reference to WUApiLib to your C# project.

using WUApiLib;
protected override void OnLoad(EventArgs e){
    base.OnLoad(e);
    UpdateSession uSession = new UpdateSession();
    IUpdateSearcher uSearcher = uSession.CreateUpdateSearcher();
    uSearcher.Online = false;
    try {
        ISearchResult sResult = uSearcher.Search("IsInstalled=1 And IsHidden=0");
        textBox1.Text = "Found " + sResult.Updates.Count + " updates" + Environment.NewLine;
        foreach (IUpdate update in sResult.Updates) {
                textBox1.AppendText(update.Title + Environment.NewLine);
        }
    }
    catch (Exception ex) {
        Console.WriteLine("Something went wrong: " + ex.Message);
    }
}

Given you have a form with a TextBox this will give you a list of the currently installed updates. See http://msdn.microsoft.com/en-us/library/aa387102(VS.85).aspx for more documentation.

This will, however, not allow you to find KB hotfixes which are not distributed via Windows Update.

Christoph Grimmer
  • 4,210
  • 4
  • 40
  • 64
4

The easiest way to do what you want is using WSUS. It's free and basically lets you setup your own local windows update server where you decide which updates are "approved" for your computers. Neither the WSUS server nor the clients need to be in a domain, though it makes it easier to configure the clients if they are. If you have different sets of machines that need different sets of updates approved, that's also supported.

Not only does this accomplish your stated goal, it saves your overall network bandwidth as well by only downloading the updates once from the WSUS server.

Ryan Bolger
  • 1,275
  • 8
  • 20
3

If in your context you're allowed to use Windows Server Update Service (WSUS), it will give you access to the Microsoft.UpdateServices.Administration Namespace.

From there, you should be able to do some nice things :)

P-L
  • 523
  • 4
  • 14
1

P-L right. I tried first the Christoph Grimmer-Die method, and in some case, it was not working. I guess it was due to different version of .net or OS architecture (32 or 64 bits). Then, to be sure that my program get always the Windows Update waiting list of each of my computer domain, I did the following :

  • Install a serveur with WSUS (may save some internet bandwith) : http://www.microsoft.com/en-us/download/details.aspx?displaylang=en&id=5216
  • Add all your workstations & servers to your WSUS server

  • Get SimpleImpersonation Lib to run this program with different admin right (optional)

  • Install only the administration console component on your dev workstation and run the following program :

It will print in the console all Windows updates with UpdateInstallationStates.Downloaded

using System;
using Microsoft.UpdateServices.Administration;
using SimpleImpersonation;

namespace MAJSRS_CalendarChecker
{
    class WSUS
    {
        public WSUS()
        {
            // I use impersonation to use other logon than mine. Remove the following "using" if not needed
            using (Impersonation.LogonUser("mydomain.local", "admin_account_wsus", "Password", LogonType.Batch))
            {
                ComputerTargetScope scope = new ComputerTargetScope();
                IUpdateServer server = AdminProxy.GetUpdateServer("wsus_server.mydomain.local", false, 80);
                ComputerTargetCollection targets = server.GetComputerTargets(scope);
                // Search
                targets = server.SearchComputerTargets("any_server_name_or_ip");

                // To get only on server FindTarget method
                IComputerTarget target = FindTarget(targets, "any_server_name_or_ip");
                Console.WriteLine(target.FullDomainName); 
                IUpdateSummary summary = target.GetUpdateInstallationSummary();
                UpdateScope _updateScope = new UpdateScope();
                // See in UpdateInstallationStates all other properties criteria
                _updateScope.IncludedInstallationStates = UpdateInstallationStates.Downloaded;
                UpdateInstallationInfoCollection updatesInfo = target.GetUpdateInstallationInfoPerUpdate(_updateScope);

                int updateCount = updatesInfo.Count;

                foreach (IUpdateInstallationInfo updateInfo in updatesInfo)
                {
                    Console.WriteLine(updateInfo.GetUpdate().Title);
                }
            }
        }
        public IComputerTarget FindTarget(ComputerTargetCollection coll, string computername)
        {
            foreach (IComputerTarget target in coll)
            {
                if (target.FullDomainName.Contains(computername.ToLower()))
                    return target;
            }
            return null;
        }
    }
}
Xavius Pupuss
  • 160
  • 1
  • 6