How to Determine All Approved Updates
Applies To: Windows Server Update Services
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
Add the
Microsoft.UpdateServices.Administration
assembly to your project.Insert a
using
statement for theMicrosoft.UpdateServices.Administration
namespace.using Microsoft.UpdateServices.Administration;
Using the
AdminProxy.GetUpdateServer
method, connect to the local WSUS server.// Connect to the local server IUpdateServer updateServer = AdminProxy.GetUpdateServer();
Instantiate an
UpdateScope
object and after setting itsApprovedStates
property to reflect the updates you’re looking for, call theIUpdateServer.GetUpdates
method, passing in theUpdateScope
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);
Calling the
IUpdate.GetUpdateApprovals
method once for each update is inefficient in this particular case. Therefore, call theIUpdateServer.GetUpdateApprovals
method to get all approvals for all updates at once.// Get all approvals for all updates at once UpdateApprovalCollection allUpdateApprovals = updateServer.GetUpdateApprovals(updateScope);
Instantiate a .NET Dictionary object that will have as its key the
UpdateRevisionId
and, as its value, anUpdateApprovalCollection
object containing all approvals for thatUpdateRevisionId
.// 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); }
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();
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>();
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); }
Code a
foreach
loop that will iterate through all of the updates returned from theIUpdateServer.GetUpdates
method call. If theIUpdate.IsApproved
property is set totrue
, a helper method (WriteApprovals
) is called. (TheWriterApproval
method is listed in the next section along with all of the source code for this sample.) If theIUpdate.IsApproved
property isfalse
and theIUpdateHasStaleUpdateApprovals
property istrue
, the code loops through all approved older revisions, calling theWriteApprovals
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();
}
}
}
}