How to Determine All Approved Updates

Use the following procedure to determine all approved updates for the current Windows Server Update Services (WSUS) server. The example that follows shows a working command-line application where all approved updates are written to an XML file for reporting purposes.

To determine all approved updates

  1. Add the Microsoft.UpdateServices.Administration assembly to your project.

  2. Insert a using statement for the Microsoft.UpdateServices.Administration namespace.

    using Microsoft.UpdateServices.Administration;
    
  3. Using the AdminProxy.GetUpdateServer method, connect to the local WSUS server.

    // Connect to the local server
    IUpdateServer updateServer = AdminProxy.GetUpdateServer();
    
  4. Instantiate an UpdateScope object and after setting its ApprovedStates property to reflect the updates you’re looking for, call the IUpdateServer.GetUpdates method, passing in the UpdateScope object.

    // Get the list of updates that are approved or that have an older revision that is approved
    UpdateScope updateScope = new UpdateScope();
    updateScope.ApprovedStates = ApprovedStates.HasStaleUpdateApprovals | ApprovedStates.LatestRevisionApproved;
    UpdateCollection updates = updateServer.GetUpdates(updateScope);
    
    
  5. Calling the IUpdate.GetUpdateApprovals method once for each update is inefficient in this particular case. Therefore, call the IUpdateServer.GetUpdateApprovals method to get all approvals for all updates at once.

    // Get all approvals for all updates at once
    UpdateApprovalCollection allUpdateApprovals = updateServer.GetUpdateApprovals(updateScope);
    
    
  6. Instantiate a .NET Dictionary object that will have as its key the UpdateRevisionId and, as its value, an UpdateApprovalCollection object containing all approvals for that UpdateRevisionId.

    // Create a dictionary so we can look up the list of approvals for any given update
    Dictionary<UpdateRevisionId, UpdateApprovalCollection> updateApprovalDictionary = new Dictionary<UpdateRevisionId, UpdateApprovalCollection>();
    foreach (IUpdateApproval updateApproval in allUpdateApprovals)
    {
       // If there is no entry in the dictionary for this update, then add one
       if (!updateApprovalDictionary.ContainsKey(updateApproval.UpdateId))
       {
          updateApprovalDictionary.Add(updateApproval.UpdateId, new UpdateApprovalCollection());
       }
    
       // Add this approval to the corresponding update's list of approvals
       updateApprovalDictionary[updateApproval.UpdateId].Add(updateApproval);
    }
    
    
  7. Using the IUpdateServer.GetComputerTargetGroups method, get the collection of all target groups for the WSUS server.

    // Get all target groups
    ComputerTargetGroupCollection allTargetGroups = new ComputerTargetGroupCollection();
    allTargetGroups = updateServer.GetComputerTargetGroups();
    
    
  8. Instantiate a .NET Dictionary object that will have as its key the target group GUID and, as its value, the corresponding IComputerTargetGroup object.

    // Create a dictionary for the target groups (GUID -> IComputerTargetGroup)
    Dictionary<Guid, IComputerTargetGroup> targetGroupDictionary = new Dictionary<Guid, IComputerTargetGroup>();
    
    
  9. For each target group, add an entry in the dictionary pointing the target group GUID to the IComputerTargetGroup object.

    // For each target group, add an entry in the dictionary pointing the target group GUID to the IComputerTargetGroup object
    foreach (IComputerTargetGroup targetGroup in allTargetGroups)
    {
       targetGroupDictionary.Add(targetGroup.Id, targetGroup);
    }
    
  10. Code a foreach loop that will iterate through all of the updates returned from the IUpdateServer.GetUpdates method call. If the IUpdate.IsApproved property is set to true, a helper method (WriteApprovals) is called. (The WriterApproval method is listed in the next section along with all of the source code for this sample.) If the IUpdate.IsApproved property is false and the IUpdateHasStaleUpdateApprovals property is true, the code loops through all approved older revisions, calling the WriteApprovals method for each.

    
    //Loop through the updates, writing any approvals they have to the XML file
    foreach (IUpdate update in updates)
    {
       ...
       if (update.IsApproved == true)
       {
          //This revision (the latest revision) is approved; get the approvals and write them
          WriteApprovals(xmlWriter, update.Id.RevisionNumber, updateApprovalDictionary[update.Id], targetGroupDictionary);
       }
       else if (update.HasStaleUpdateApprovals) 
       {
          //This revision has older revisions that are approved; get their approvals and write them
          foreach (IUpdate revision in update.GetRelatedUpdates(UpdateRelationship.AllRevisionsOfThisUpdate))
          {
             //If this revision is approved then write its approvals
             if (revision.IsApproved)
             {
                WriteApprovals(xmlWriter, revision.Id.RevisionNumber, revision.GetUpdateApprovals(), targetGroupDictionary);
             }
          }
       }
    }
    
    

Example

The following is the complete code listing for a console application that approves the specified update for optional install.

/*----------------------------------------------------------------------
This file is part of the Microsoft Windows Server Update Services
API Code Samples.

DISCLAIMER OF WARRANTY: THIS CODE AND INFORMATION ARE PROVIDED "AS-IS."  
YOU BEAR THE RISK OF USING IT.  MICROSOFT GIVES NO EXPRESS WARRANTIES, 
GUARANTEES OR CONDITIONS.  YOU MAY HAVE ADDITIONAL CONSUMER RIGHTS 
UNDER YOUR LOCAL LAWS WHICH THIS AGREEMENT CANNOT CHANGE.  
TO THE EXTENT PERMITTED UNDER YOUR LOCAL LAWS, MICROSOFT EXCLUDES 
THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 
PURPOSE AND NON-INFRINGEMENT.
----------------------------------------------------------------------*/

/* 
 * This application:
 *  1. Connects to the local WSUS server
 *  2. Gets a list of updates that are approved or that have an older revision that was approved
 *  3. Gets all approvals for all updates
 *  4. Loops through the updates, writing to an XML file all approvals
*/

using System;
using Microsoft.UpdateServices.Administration;
using System.Xml;
using System.Collections.Generic;
using System.Text;

namespace WsusSamples
{
  class DetermineAllApprovedUpdates
  {
    static void Main(string[] args)
    {
      try
      {
        Console.WriteLine("Getting list of approved updates");

        // Create the XML file that will hold our output
        string fileName = String.Format("ApprovedUpdates {0}.xml", DateTime.Now.ToLongDateString());
        XmlTextWriter xmlWriter = new XmlTextWriter(fileName, System.Text.Encoding.UTF8);
        xmlWriter.Formatting = Formatting.Indented;
        xmlWriter.Indentation = 4;
        xmlWriter.WriteStartDocument(true);

        // Connect to the local server
        IUpdateServer updateServer = AdminProxy.GetUpdateServer();

        // Get the list of updates that are approved or that have an older revision that is approved
        UpdateScope updateScope = new UpdateScope();
        updateScope.ApprovedStates = ApprovedStates.HasStaleUpdateApprovals | ApprovedStates.LatestRevisionApproved;
        UpdateCollection updates = updateServer.GetUpdates(updateScope);

        // Get all approvals for all updates at once
        UpdateApprovalCollection allUpdateApprovals = updateServer.GetUpdateApprovals(updateScope);

        // Create a dictionary so we can look up the list of approvals for any given update
        Dictionary<UpdateRevisionId, UpdateApprovalCollection> updateApprovalDictionary = new Dictionary<UpdateRevisionId, UpdateApprovalCollection>();
        foreach (IUpdateApproval updateApproval in allUpdateApprovals)
        {
          // If there is no entry in the dictionary for this update, then add one
          if (!updateApprovalDictionary.ContainsKey(updateApproval.UpdateId))
          {
            updateApprovalDictionary.Add(updateApproval.UpdateId, new UpdateApprovalCollection());
          }

          // Add this approval to the corresponding update's list of approvals
          updateApprovalDictionary[updateApproval.UpdateId].Add(updateApproval);
        }

        // Get all target groups
        ComputerTargetGroupCollection allTargetGroups = new ComputerTargetGroupCollection();
        allTargetGroups = updateServer.GetComputerTargetGroups();

        // Create a dictionary for the target groups (GUID -> IComputerTargetGroup)
        Dictionary<Guid, IComputerTargetGroup> targetGroupDictionary = new Dictionary<Guid, IComputerTargetGroup>();

        // For each target group, add an entry in the dictionary pointing the target group GUID to the IComputerTargetGroup object
        foreach (IComputerTargetGroup targetGroup in allTargetGroups)
        {
          targetGroupDictionary.Add(targetGroup.Id, targetGroup);
        }

        // <ApprovedUpdates>
        xmlWriter.WriteStartElement("ApprovedUpdates");

        //Loop through the updates, writing any approvals they have to the XML file
        foreach (IUpdate update in updates)
        {
          //<Update Id="update ID" UpdateTitle="title" Classification="classification">
          xmlWriter.WriteStartElement("Update");
          xmlWriter.WriteAttributeString("Id", update.Id.UpdateId.ToString());
          xmlWriter.WriteAttributeString("UpdateTitle", update.Title);
          xmlWriter.WriteAttributeString("Classification", update.UpdateClassificationTitle);

          //<Approvals>
          xmlWriter.WriteStartElement("Approvals");

          if (update.IsApproved == true)
          {
            //This revision (the latest revision) is approved; get the approvals and write them
            WriteApprovals(xmlWriter, update.Id.RevisionNumber, updateApprovalDictionary[update.Id], targetGroupDictionary);
          }
          else if (update.HasStaleUpdateApprovals) 
          {
            //This revision has older revisions that are approved; get their approvals and write them
            foreach (IUpdate revision in update.GetRelatedUpdates(UpdateRelationship.AllRevisionsOfThisUpdate))
            {
              //If this revision is approved then write its approvals
              if (revision.IsApproved)
              {
                WriteApprovals(xmlWriter, revision.Id.RevisionNumber, revision.GetUpdateApprovals(), targetGroupDictionary);
              }
            }
          }

          //</Approvals>
          xmlWriter.WriteEndElement();

          // </Update>
          xmlWriter.WriteEndElement();
        }

        //</ApprovedUpdates>
        xmlWriter.WriteEndElement();

        //done writing the document
        xmlWriter.Close();
        xmlWriter = null;

        Console.WriteLine("Complete. Results written to the {0} file in the current folder", fileName);
      }
      catch (Exception ex)
      {
        Console.WriteLine("An error occurred:\r\n" +
                          "Error text: {0}\r\n" +
                          "Stack trace: {1}\r\n",
                          ex.Message, ex.StackTrace);
      }
    }

    static void WriteApprovals(XmlTextWriter xmlWriter, 
                               int revisionNumber, 
                               UpdateApprovalCollection updateApprovals, 
                               Dictionary<Guid, IComputerTargetGroup> targetGroupDictionary)
    {
      //loop through the approvals for the update
      foreach (IUpdateApproval approval in updateApprovals)
      {
          StringBuilder deadline = new StringBuilder();

          //is there a deadline?
          if (approval.Deadline < DateTime.MaxValue) 
          {
            deadline.Append(approval.Deadline.ToLongDateString() + " " + approval.Deadline.ToShortTimeString());
          }
          else deadline.Append("None");

          //<Approval RevisionNumber="update revision number" TargetGroup="target group name" Approval="approval action" Deadline="deadline" ApprovalDate="approval date">
          xmlWriter.WriteStartElement("Approval");
          xmlWriter.WriteAttributeString("RevisionNumber", revisionNumber.ToString());
          xmlWriter.WriteAttributeString("TargetGroup", targetGroupDictionary[approval.ComputerTargetGroupId].Name);
          xmlWriter.WriteAttributeString("Approval", approval.Action.ToString());
          xmlWriter.WriteAttributeString("Deadline", deadline.ToString());
          xmlWriter.WriteAttributeString("ApprovalDate", approval.CreationDate.ToString());

          //</Approval>
          xmlWriter.WriteEndElement();
      }
    }
  }
}

Show:
© 2014 Microsoft. All rights reserved.