Background
We all know how important WSUS maintenance is and there are numerous posts on how to automate and the scripts/queries to run.
Have a read through This amazing Blog from Meghan Stewart | Support Escalation Engineer if you are looking at automating the WSUS Maintenance. It has all the required information on When, Why and How to implement your WSUS Maintenance, as well as having a great PowerShell script to help..
But… have you ever just needed to kick of WSUS maintenance or SQL defrag remotely and on multiple servers at the same time. I had this requirement a while back where the customer has 150 secondary sites with Software Update Points installed and wanted to do WSUS maintenance but only when they had a change window available and also create a log file in a central share – so NOT fully automated!!
So I decided to put the ‘scripts’ feature in SCCM to the test and try implement a solution to assist the customer.
Solution
Important Considerations
Before we get started, it’s important that I mention a few things:
- Remember that when doing WSUS maintenance when you have downstream servers, you add to the WSUS servers from the top down, but remove from the bottom up. So if you are syncing/adding updates, they flow into the top (upstream WSUS server) then replicate down to the downstream servers. When you do a cleanup, you are removing things from the WSUS servers, so you should remove from the bottom of the hierarchy and allow the changes to flow up to the top.
- It’s important to note that this WSUS maintenance can be performed simultaneously on multiple servers in the same tier. You do however want to make sure that one tier is done before moving onto the next one when doing a cleanup. The cleanup and re-index steps I talk about below should be run on all WSUS servers regardless of whether they are a replica WSUS server or not.
- This is a big one. You must ensure that you do not sync your SUPs during this maintenance process as it is possible you will lose some of the work you have already done if you do. You may want to check your SUP sync schedule and set it to manual during this process.
Step 1 – Create Software Update Point Collections
The first step will be to create the collections that we will run the script against.
Below is the 2 collections for the Primary(Upstream WSUS) and secondary(Downstream WSUS) servers
Step 2 – Create Scripts in SCCM
The next step was to create the scripts in SCCM which will be used to run against the above collections created.
- Create a share on a server and copy the below .ps1 and .sql files into the share
- Create a log file folder beneath that where the output logs will be written to
-
WSUS database(SUSDB) Re-index script
PowerShell Script (SUSDB_Reindex.ps1):
$Logfile = $env:computername + "_reindex"
Invoke-sqlcmd -ServerInstance "localhost" -Database "SUSDB" -InputFile "\\ServerName\Share\Scripts\WSUS_Cleanup\SUSDB_reindex.sql" -Verbose *> "C:\Windows\Temp\$Logfile.log"
cd e:
copy-item C:\Windows\Temp\$Logfile.log -destination \\ServerName\Share\Scripts\WSUS_Cleanup\Logs\
exit $LASTEXITCODE
- script runs “SUSDB_reindex.sql” file against each server in the collection
- Outputs a logfile to the specified share
Note: Change Servername, share and e: to the drive letter where scripts are located
-
WSUS database(SUSDB) Cleanup
PowerShell Script (SUSDB_Cleanup.ps1):
$Logfile = $env:computername + "_cleanup"
Invoke-sqlcmd -ServerInstance "localhost" -Database "SUSDB" -ConnectionTimeout "0" -QueryTimeout "65535" -InputFile "\\Servername\Share\Scripts\WSUS_Cleanup\SUSDB_Cleanup.sql" -Verbose *> "C:\Windows\Temp\$Logfile.log"
cd e:
copy-item C:\Windows\Temp\$Logfile.log -destination \\Servername\Share\Scripts\WSUS_Cleanup\Logs
exit $LASTEXITCODE
- script runs “SUSDB_Cleanup.sql” file against each server in the collection
- Outputs a logfile to the specified share
Note: Change Servername, share and e: to the drive letter where scripts are located
SQL script (SUSDB_Cleanup.sql):
use susdb DECLARE @msg nvarchar(100) DECLARE @NumberRecords int, @RowCount int, @var1 int -- Create a temporary table with an Identity column CREATE TABLE #results (RowID INT IDENTITY(1, 1), Col1 INT) -- Call the Stored Procedure to get the updates to delete & insert them into the table INSERT INTO #results(Col1) EXEC spGetObsoleteUpdatesToCleanup -- Get the number of records in the temporary table SET @NumberRecords = @@ROWCOUNT SET @RowCount = 1 -- Show records in the temporary table select * from #results -- Loop through all records in the temporary table -- using the WHILE loop construct & call the Stored Procedure to delete them WHILE @RowCount <= @NumberRecords BEGIN SELECT @var1 = Col1 FROM #results where RowID = @rowcount SET @msg = 'Deleting UpdateID ' + CONVERT(varchar(10), @var1) + ', Rowcount '+ CONVERT(varchar(10), @rowcount) RAISERROR(@msg,0,1) WITH NOWAIT EXEC spDeleteUpdate @localUpdateID=@var1 SET @RowCount = @RowCount + 1 END -- Drop the temporary table when completed DROP TABLE #results
-
WSUS Cleanup
PowerShell Script (WSUS_Cleanup.ps1):
$WSUSServer = @( (hostname) ) Get-WsusServer -Name localhost -PortNumber 8530 | Invoke-WsusServerCleanup -CleanupObsoleteComputers -CleanupObsoleteUpdates -CleanupUnneededContentFiles -CompressUpdates -DeclineExpiredUpdates -Verbose *> "\\Servername\Share\Scripts\WSUS_Cleanup\Logs\$wsusserver _WSUSCleanup.log"
- script runs WsusServerCleanup against each server in the collection
- Outputs a logfile to the specified share
Note: Change Servername, share and e: to the drive letter where scripts are located
All that's left is to import them into SCCM.
- In the Configuration Manager console, click Software Library.
- In the Software Library workspace, click Scripts.
- On the Home tab, in the Create group, click Create Script.
- On the Script page of the Create Script wizard, configure the following settings:
- Script Name - Enter a name for the script. Although you can create multiple scripts with the same name, using duplicate names makes it harder for you to find the script you need in the Configuration Manager console.
- Script language - Currently, only PowerShell scripts are supported.
- Import - Import a PowerShell script into the console. The script is displayed in the Script field.
- Clear - Removes the current script from the Script field.
- Script - Displays the currently imported script. You can edit the script in this field as necessary.
- Complete the wizard. The new script is displayed in the Script list with a status of Waiting for approval. Before you can run this script on client devices, you must approve it.
Scripts must be approved, by the script approver role, before they can be run. To approve a script:
- In the Configuration Manager console, click Software Library.
- In the Software Library workspace, click Scripts.
- In the Script list, choose the script you want to approve or deny and then, on the Home tab, in the Script group, click Approve/Deny.
- In the Approve or deny script dialog box, select Approve, or Deny for the script. Optionally, enter a comment about your decision. If you deny a script, it cannot be run on client devices.
- Complete the wizard. In the Script list, you see the Approval State column change depending on the action you took.
Step 3 – Running The Scripts in SCCM
The final step now once the scripts have been added to SCCM is just to run the scripts and wait….
-
- In the Configuration Manager console, click Assets and Compliance.
- In the Assets and Compliance workspace, click Device Collections.
- In the Device Collections list, click the collection of devices on which you want to run the script.
- Select a collection of your choice, click Run Script.
- On the Script page of the Run Script wizard, choose a script from the list. Only approved scripts are shown.
- Click Next, and then complete the wizard.
Important
If a script does not run, for example because a target device is turned off during the one hour time period, you must run it again.
Script Monitoring and Output LogFiles:
- In the Configuration Manager console, click Monitoring.
- In the Monitoring workspace, click Script Status.
- In the Script Status list, you view the results for each script you ran on client devices. A script exit code of 0 generally indicates that the script ran successfully.
- Beginning in Configuration Manager 1802, script output is truncated to 4 KB to allow for better display experience.
- Beginning in Configuration Manager 1802, script output is truncated to 4 KB to allow for better display experience.
Below is the Output from the scripts run above:
Conclusion
In this post, I demonstrated how we can use the ‘scripts’ feature in SCCM to initiate WSUS Cleanup scripts on demand. Hopefully this is helpful to you but also shows you the capability of the feature for almost anything . Till next time…
Disclaimer – All scripts and reports are provided ‘AS IS’
This sample scripts are not supported under any Microsoft standard support program or service. This sample scripts are provided AS IS without warranty of any kind. Microsoft further disclaims all implied warranties including, without limitation, any implied warranties of merchantability or of fitness for a particular purpose. The entire risk arising out of the use or performance of these sample scripts and documentation remains with you. In no event shall Microsoft, its authors, or anyone else involved in the creation, production, or delivery of these scripts be liable for any damages whatsoever (including, without limitation, damages for loss of business profits, business interruption, loss of business information, or other pecuniary loss) arising out of the use of or inability to use these sample scripts or documentation, even if Microsoft has been advised of the possibility of such damages.