View RSS Feed

Cache

A Useful WSUS Script

Rate this Entry
by , 17th August 2010 at 10:53 PM (6660 Views)
All my computers on WSUS are currently sitting in Unassigned apart from the Servers which has worked quite well - until now.

I want to control the Roll Out of XP SP3 to computers so that I can make my way arround them using WSUS without cause people any major problems because someone shuts the computer down, it starts to install and then the computer is needed for the next lesson.

The Answer I thought - create a sub group of computers!

One snag - Unassigned Computers can't contain a sub group.

So, I decided to create a new Group and a Sub Group of that for SP3. Now, what about the approvals which I've just got on unassigned computers. There aren't a huge ammount, mostly just .net updates which I don't have room to install on the servers as of yet until they are rebuilt, however it still means going through and approving a few updates for that one group.

I stumbled across an answer though!

Through the API's you can access WSUS and the groups and copy the approvals between groups, but the GUI doesn't allow this.

The solution came from this page: http://msmvps.com/blogs/athif/archiv.../05/89368.aspx

I've copied below for reference:

Code:
1) Copy the code between the two ----------------8<-----------------
below and save it to a text file named "CopyApprovalsBetweenGroups.cs"

2) Open a command prompt, and navigate to the directory containing
CopyApprovalsBetweenGroups.cs.

3) Run the following command line (all one one line, you will need to
unwrap the line before running it!):

%WINDIR%\Microsoft.NET\Framework\v1.1.4322\csc.exe
  /r:"%PROGRAMFILES%\Update Services\service\bin
\Microsoft.UpdateServices.Administration.dll" /target:exe
  /out:CopyApprovalsBetweenGroups.exe CopyApprovalsBetweenGroups.cs

This will create a tool called CopyApprovalsBetweenGroups.exe.

(Note if you use Visual Studio to compile the code instead of using the command line above, you need to add a reference to the file microsoft.updateservices.administration.dll in your project, see
bottom of this Web page for more on this:
http://download.microsoft.com/download/7/4/5/7458e392-11de-4543-936c-b5248e344487/readme.htm)


Content of CopyApprovalsBetweenGroups.cs:
--------------------8<----------------------

using System;
using Microsoft.UpdateServices.Administration;

// Usage:
// copyapprovals <name of group to copy from> <name of group to copy to>
class Program
{
  static IComputerTargetGroup FindComputerTargetGroup(
   ComputerTargetGroupCollection groups,
   string name)
  {
   foreach (IComputerTargetGroup group in groups)
   {
    if (group.Name == name)
    {
     return group;
    }
   }

   throw new ApplicationException(string.Format("Computer group {0} not found.", name));
  }

  static void Main(string[] args)
  {
   try
   {
    if (args.Length != 2)
    {
     //System.Windows.Forms.MessageBox.Show("TEST");
     Console.WriteLine("Incorrect number of arguments.");
     Console.WriteLine("usage: copyapprovals <name of group to copy from>" +
      " <name of group to copy to>");
     Console.ReadLine();
     return;
    }

    IUpdateServer server = AdminProxy.GetUpdateServer();
    ComputerTargetGroupCollection groups = server.GetComputerTargetGroups();

    // get IComputerTargetGroup references for the source and destination groups
    IComputerTargetGroup sourceGroup = FindComputerTargetGroup(groups, args[0]);
    IComputerTargetGroup destinationGroup = FindComputerTargetGroup(groups, args[1]);

    Console.WriteLine("Copying update approvals from group {0} to group {1}.", args[0],
     args[1]);

    // loop over all updates, copying approvals from the source group to the destination
    // group as necessary
    UpdateCollection updates = server.GetUpdates();

    foreach (IUpdate update in updates)
    {
     UpdateApprovalCollection sourceApprovals = update.GetUpdateApprovals(sourceGroup);
     UpdateApprovalCollection destinationApprovals =
       update.GetUpdateApprovals(destinationGroup);

     // for simplicity, this program assumes that an update has
     // at most one approval to a given group
     if (sourceApprovals.Count > 1)
     {
      Console.WriteLine(
       "Update {0} had multiple approvals to group {1}; skipping.",
       update.Title,
       sourceGroup.Name);
      continue;
     }
     if (destinationApprovals.Count > 1)
     {
      Console.WriteLine(
       "Update {0} had multiple approvals to group {1}; skipping.",
       update.Title,
       destinationGroup.Name);
      continue;
     }

     IUpdateApproval sourceApproval = null;
     IUpdateApproval destinationApproval = null;

     if (sourceApprovals.Count > 0)
     {
      sourceApproval = sourceApprovals[0];
     }
     if (destinationApprovals.Count > 0)
     {
      destinationApproval = destinationApprovals[0];
     }

     if (sourceApproval == null)
     {
      // the update is not approved to the source group

      if (destinationApproval != null)
      {
       // the update is not approved to the source group, but it is approved
       // to the destination group
       // unapprove the update for the destination group to match the source
       Console.WriteLine(
        "Unapproving update {0} to group {1}.",
        update.Title,
        destinationGroup.Name);
       destinationApproval.Delete();
      }
      else
      {
       // neither the source group nor the destination group have an approval;
       // do nothing
      }
     }
     else
     {
      // the source group has an approval

      if (destinationApproval != null)
      {
       // destination group has an approval; check to see if we need to overwrite it
       if (destinationApproval.Action !=sourceApproval.Action)
       {
        // the approvals are different; overwrite
        Console.WriteLine(
         "Changing approval for update {0} from {1} to {2} for group {3}.",
         update.Title,
         destinationApproval.Action,
         sourceApproval.Action,
         destinationGroup.Name);
        update.Approve(sourceApproval.Action, destinationGroup);
       }
      }
      else
      {
       // destination group does not have an approval; approve
       Console.WriteLine(
        "Approving update {0} for {1} for group {2}.",
        update.Title,
        sourceApproval.Action,
        destinationGroup.Name);
       update.Approve(sourceApproval.Action, destinationGroup);
      }
     }
    }
   }
   catch (Exception e)
   {
    Console.WriteLine(e.Message);
   }
  }
}

--------------------8<----------------------
The only variation of the code I had to use was step 3. The line I had to use was:

Code:
%WINDIR%\Microsoft.NET\Framework\v2.0.50727\csc.exe /r:"%PROGRAMFILES%\Update Services\service\bin\Microsoft.UpdateServices.Administration.dll" /target:exe /out:CopyApprovalsBetweenGroups.exe CopyApprovalsBetweenGroups.cs
Initially got a File Not Found error, this was because the .net directory wasn't correct, so if you have the same issue, check what the .net v2 Framework folder is called and rename accordingly.

Once it's compiled an exe, load a command prompt and run:

CopyApprovalsBetweenGroups.exe "Source Group" "Destination Group"

The group is case sensitive, so make sure you type it exactly as it appears in your WSUS console.

Updated 17th August 2010 at 10:56 PM by Cache

Categories
Uncategorized

Comments

Trackbacks

Total Trackbacks 0
Trackback URL: