So, let’s cover these options one by one.
0) Preperations
First we would have to start with loading the assembly for WSUS. This can be done with the following command:
First we would have to start with loading the assembly for WSUS. This can be done with the following command:
1
| [reflection.assembly] ::LoadWithPartialName( "Microsoft.UpdateServices.Administration" ) |
* If you don’t want any output shown by that command, simply pipe it to Out-Null
Next we would need to create a PowerShell object for the WSUS clean up scope, which is part of the assembly:
1
| $CleanUpScope = New-Object Microsoft.UpdateServices.Administration.CleanupScope |
1) Unused Updates and Update Revisions
Here’s the first of the options shown in the GUI. What would be the PowerShell way to accomplish this?
To cleanup unused (in fact: obsolete) updates:
Here’s the first of the options shown in the GUI. What would be the PowerShell way to accomplish this?
To cleanup unused (in fact: obsolete) updates:
1
| $CleanUpScope .CleanObsoleteUpdates = $true |
To cleanup update revisions:
<See point 5 for that>
2) Computers not contacting the server
For the second option shown in the GUI we can use the following PowerShell command:
For the second option shown in the GUI we can use the following PowerShell command:
1
| $cleanUpScope .CleanupObsoleteComputers = $true |
3) Unneeded update files
This option can be a real storage saver as I found out myself. To cleanup all unneeded update files:
This option can be a real storage saver as I found out myself. To cleanup all unneeded update files:
1
| $cleanUpScope .CleanupUnneededContentFiles = $true |
4) Expired Updates
As time passes some updates may become expired. To cleanup (in fact: decline) those updates:
As time passes some updates may become expired. To cleanup (in fact: decline) those updates:
1
| $cleanUpScope .DeclineExpiredUpdates = $true |
5) Superseded Updates
And the last option in the GUI, to cleanup (in fact: decline) superseded updates:
And the last option in the GUI, to cleanup (in fact: decline) superseded updates:
1
| $cleanUpScope .DeclineSupersededUpdates = $true |
Other options available
Although the CleanUp Manager wizard did not show more options, there actually is one… Compressing updates.
I found this option by accident since I was using PowerShell ISE and its IntelliSense feature… which gave me a list with options available… and there it was, standing between the other options.
Although the CleanUp Manager wizard did not show more options, there actually is one… Compressing updates.
I found this option by accident since I was using PowerShell ISE and its IntelliSense feature… which gave me a list with options available… and there it was, standing between the other options.
This can be configured with the following command:
1
| $cleanUpScope .CompressUpdates = $true |
Executing the tasks
Now that we’ve got our variables set, we can execute the cleanup task(s) based on those variables.
First we would have to load the WSUS server into a variable. This can be done by using that assembly again, with a little adaptation so that we can use the cleanup manager later on:
Now that we’ve got our variables set, we can execute the cleanup task(s) based on those variables.
First we would have to load the WSUS server into a variable. This can be done by using that assembly again, with a little adaptation so that we can use the cleanup manager later on:
1
| $WSUSServer = [Microsoft.UpdateServices.Administration.AdminProxy] ::GetUpdateServer() |
Now that the server is loaded into a variable, we can use that variable to call for the CleanUp Manager:
1
| $cleanUpManager = $WSUSServer .GetCleanupManager() |
Alright. The assembly is loaded, settings for the tasks have been configured, the update server is stored in a variable and the CleanUp Manager is called.
Now, to execute the actual tasks:
Now, to execute the actual tasks:
1
| $CleanUpManager .PerformCleanup( $cleanupScope ) |
My approach
Although the options (1-5) have the order in the GUI as I numbered them in this post, I’ve chosen to execute them in the following order:
1) $CleanUpScope.CleanupObsoleteComputers = $true
2) $CleanUpScope.DeclineSupersededUpdates = $true
3) $CleanUpScope.DeclineExpiredUpdates = $true
4) $CleanUpScope.CleanObsoleteUpdates = $true
5) $CleanUpScope.CleanupUnneededContentFiles = $true
6) $CleanUpScope.CompressUpdates = $true
Although the options (1-5) have the order in the GUI as I numbered them in this post, I’ve chosen to execute them in the following order:
1) $CleanUpScope.CleanupObsoleteComputers = $true
2) $CleanUpScope.DeclineSupersededUpdates = $true
3) $CleanUpScope.DeclineExpiredUpdates = $true
4) $CleanUpScope.CleanObsoleteUpdates = $true
5) $CleanUpScope.CleanupUnneededContentFiles = $true
6) $CleanUpScope.CompressUpdates = $true
Why this order?
Well, think about it. First you would want to cleanup the list of computers, then the updates, then the actual content files and last you would want to compress the files that are left… right?
Well, think about it. First you would want to cleanup the list of computers, then the updates, then the actual content files and last you would want to compress the files that are left… right?
My script
1
2
3
4
5
6
7
8
9
10
11
12
13
| [reflection.assembly] ::LoadWithPartialName( "Microsoft.UpdateServices.Administration" ) | Out-Null $WSUSServer = [Microsoft.UpdateServices.Administration.AdminProxy] ::GetUpdateServer() $CleanUpScope = New-Object Microsoft.UpdateServices.Administration.CleanupScope $CleanUpScope .CleanupObsoleteComputers = $true $CleanUpScope .DeclineSupersededUpdates = $true $CleanUpScope .DeclineExpiredUpdates = $true $CleanUpScope .CleanObsoleteUpdates = $true $CleanUpScope .CleanupUnneededContentFiles = $true $CleanUpScope .CompressUpdates = $true $CleanUpManager = $WSUSServer .GetCleanupManager() $CleanUpManager .PerformCleanup( $CleanUpScope )
|