<?xml version="1.0" encoding="ISO-8859-1"?>

<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
	<channel>
		<title>EduGeek.net - Blogs - Cache</title>
		<link>http://www.edugeek.net/blogs/cache/</link>
		<description><![CDATA[EduGeek.net - The I.T. professionals' life line]]></description>
		<language>en</language>
		<lastBuildDate>Sat, 25 May 2013 06:13:16 GMT</lastBuildDate>
		<generator>vBulletin</generator>
		<ttl>2</ttl>
		<image>
			<url>http://staticc3.cdngeek.net/images/misc/rss.jpg</url>
			<title>EduGeek.net - Blogs - Cache</title>
			<link>http://www.edugeek.net/blogs/cache/</link>
		</image>
		<item>
			<title>A Useful WSUS Script</title>
			<link>http://www.edugeek.net/blogs/cache/402-useful-wsus-script.html</link>
			<pubDate>Tue, 17 Aug 2010 21:53:58 GMT</pubDate>
			<description>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...</description>
			<content:encoded><![CDATA[<blockquote class="blogcontent restore">All my computers on WSUS are currently sitting in Unassigned apart from the Servers which has worked quite well - until now.<br />
<br />
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.<br />
<br />
The Answer I thought - create a sub group of computers!<br />
<br />
One snag - Unassigned Computers can't contain a sub group.<br />
<br />
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.<br />
<br />
I stumbled across an answer though!<br />
<br />
Through the API's you can access WSUS and the groups and copy the approvals between groups, but the GUI doesn't allow this.<br />
<br />
The solution came from this page: <a href="http://msmvps.com/blogs/athif/archive/2006/04/05/89368.aspx" target="_blank">http://msmvps.com/blogs/athif/archiv.../05/89368.aspx</a><br />
<br />
I've copied below for reference:<br />
<br />
<div class="bbcode_container">
	<div class="bbcode_description">Code:</div>
	<pre class="bbcode_code"style="height:372px;">1) Copy the code between the two ----------------8&lt;-----------------
below and save it to a text file named &quot;CopyApprovalsBetweenGroups.cs&quot;

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:&quot;%PROGRAMFILES%\Update Services\service\bin
\Microsoft.UpdateServices.Administration.dll&quot; /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&lt;----------------------

using System;
using Microsoft.UpdateServices.Administration;

// Usage:
// copyapprovals &lt;name of group to copy from&gt; &lt;name of group to copy to&gt;
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(&quot;Computer group {0} not found.&quot;, name));
  }

  static void Main(string[] args)
  {
   try
   {
    if (args.Length != 2)
    {
     //System.Windows.Forms.MessageBox.Show(&quot;TEST&quot;);
     Console.WriteLine(&quot;Incorrect number of arguments.&quot;);
     Console.WriteLine(&quot;usage: copyapprovals &lt;name of group to copy from&gt;&quot; +
      &quot; &lt;name of group to copy to&gt;&quot;);
     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(&quot;Copying update approvals from group {0} to group {1}.&quot;, 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 &gt; 1)
     {
      Console.WriteLine(
       &quot;Update {0} had multiple approvals to group {1}; skipping.&quot;,
       update.Title,
       sourceGroup.Name);
      continue;
     }
     if (destinationApprovals.Count &gt; 1)
     {
      Console.WriteLine(
       &quot;Update {0} had multiple approvals to group {1}; skipping.&quot;,
       update.Title,
       destinationGroup.Name);
      continue;
     }

     IUpdateApproval sourceApproval = null;
     IUpdateApproval destinationApproval = null;

     if (sourceApprovals.Count &gt; 0)
     {
      sourceApproval = sourceApprovals[0];
     }
     if (destinationApprovals.Count &gt; 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(
        &quot;Unapproving update {0} to group {1}.&quot;,
        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(
         &quot;Changing approval for update {0} from {1} to {2} for group {3}.&quot;,
         update.Title,
         destinationApproval.Action,
         sourceApproval.Action,
         destinationGroup.Name);
        update.Approve(sourceApproval.Action, destinationGroup);
       }
      }
      else
      {
       // destination group does not have an approval; approve
       Console.WriteLine(
        &quot;Approving update {0} for {1} for group {2}.&quot;,
        update.Title,
        sourceApproval.Action,
        destinationGroup.Name);
       update.Approve(sourceApproval.Action, destinationGroup);
      }
     }
    }
   }
   catch (Exception e)
   {
    Console.WriteLine(e.Message);
   }
  }
}

--------------------8&lt;----------------------</pre>
</div>The only variation of the code I had to use was step 3. The line I had to use was:<br />
<br />
<div class="bbcode_container">
	<div class="bbcode_description">Code:</div>
	<pre class="bbcode_code"style="height:36px;">%WINDIR%\Microsoft.NET\Framework\v2.0.50727\csc.exe /r:&quot;%PROGRAMFILES%\Update Services\service\bin\Microsoft.UpdateServices.Administration.dll&quot; /target:exe /out:CopyApprovalsBetweenGroups.exe CopyApprovalsBetweenGroups.cs</pre>
</div>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.<br />
<br />
Once it's compiled an exe, load a command prompt and run:<br />
<br />
CopyApprovalsBetweenGroups.exe &quot;Source Group&quot; &quot;Destination Group&quot;<br />
<br />
The group is case sensitive, so make sure you type it exactly as it appears in your WSUS console.</blockquote>

]]></content:encoded>
			<dc:creator>Cache</dc:creator>
			<guid isPermaLink="true">http://www.edugeek.net/blogs/cache/402-useful-wsus-script.html</guid>
		</item>
		<item>
			<title>The joys of migrating files</title>
			<link>http://www.edugeek.net/blogs/cache/342-joys-migrating-files.html</link>
			<pubDate>Sat, 12 Jun 2010 14:04:39 GMT</pubDate>
			<description><![CDATA[It's funny, I don't usual blog and tend to pop on Edugeek with problems but it's a great resource and one I'm very pleased to have found (otherwise I...]]></description>
			<content:encoded><![CDATA[<blockquote class="blogcontent restore">It's funny, I don't usual blog and tend to pop on Edugeek with problems but it's a great resource and one I'm very pleased to have found (otherwise I think by now I'd have given up all hope, especially after the last couple of weeks).<br />
<br />
But the latest problem, how to migrate a load of files, preserve permissions and do it dead easily.<br />
<br />
I've used Robocopy with the GUI in the past to move files and it worked a dream, however for whatever reason (probably me being dumb) I couldn't get it to do what I wanted, migrate all the files and preserve all ownership, time stamps, acl's ect. It is possible and now I've done it using the command line I really don't know why I couldn't do it. But I thought I'd post it up here in case anyone else wants it or I need to do it again and have exactly the same problem.<br />
<br />
First off because I couldn't do it, I started with XCOPY which was brilliant, fairly quick and did everything I needed except copy the timestamps of folders. That was done using:<br />
<br />
xcopy z:\ &quot;F:\staff shared\&quot; /E /K /O<br />
<br />
Wonderfull, but as mentioned because I'm pernickity I'd like to keep all the folder timestamps. (This will be my eventual tool for beating people round the head saying do you really need this folder from 2005/04/02 ect).<br />
<br />
And so it was back to robocopy. The eventual command line I used was:<br />
<br />
 robocopy Z:\ &quot;F:\staff shared&quot; /COPYALL /E /R:0 /DCOPY:T <br />
<br />
And off it trundelled and is doing exactly what it said on the tin and doing it brilliantly. The one little switch I couldn't work out for the GUI? /DCOPY:T which copies the directory timestamp.<br />
<br />
The only other little gotcha that caught me out, was that the destination directory, doesn't like to have a \ on the end, especially if there's a space in it. Otherwise you just get loads of access denied errors and the impossibility of working out why (especially when your logged on as Administrator).<br />
<br />
Wonderful, and now I can go back to beating staff round the head. Ideally you'd do this before you copied all of their stuff across, but time is short and I need to rebuild the server before the other one dies alas.<br />
<br />
Oh the joys of working in IT! :rolleyes:</blockquote>

]]></content:encoded>
			<dc:creator>Cache</dc:creator>
			<guid isPermaLink="true">http://www.edugeek.net/blogs/cache/342-joys-migrating-files.html</guid>
		</item>
	</channel>
</rss>
