When you have monthly software update groups that gets generated monthly by the Automatic Deployment rule (ADR) the recommendation is always to go in and delete old obsolete groups that just taking up space. Instead of manually go in and clean everything up this Powershell script below does it for you. Just make a schedule task that runs this script once a month or how often you want it run.
What do we want to achieve?
The scenario is that you have a monthly ADR running that creates a new Software Update Group every month and deploys that to the designated clients, in this case Windows 10 machines. Having the ADR creating new Software Update Groups every month is nice because it makes it easy to be able keep track of which new updates got deployed most recently since once in a while there’s a update that just break things and by having the setup like that it will make it much easier to find out which one it was and uninstall the update.
But after a certain period of time lets say a couple of month it’s not relevant to have those software groups and deployments hanging around since everything is working fine no problem has been reported regarding the updates and your images has been updated with the those updates as well so the only thing left is to delete those deployments for the Software Update Groups and also the downloaded software files.
The Script
# Configuration Variables [String]$SitePath = "TS1:" # Name of your Site and a colon [String]$sccmserver = "SCCM1" # Name of your SCCM site server [String]$GroupNameScheme = "Client_Win10_x64*" # Software update name scheme [String]$DeploymentPackage = "Client_Win10_x64 - Monthly" # Deployment package name [String]$SCCMmodule = "D:\program Files\Microsoft Configuration Manager\AdminConsole\bin\ConfigurationManager.psd1" #Specify the path to the Configmgr PS module [Int]$Days = 90 # How many days back in time you want to delete (if 90 you will delete Software Update Groups and files older then 90 days that has the name like $GroupNameScheme you declared earlier) Import-Module $SCCMmodule Set-location $SitePath # Finds and delete software update group and deployments older then specified date $Softwaregroups = get-cmsoftwareupdategroup -Name "$GroupNameScheme" | Where-Object {$_.DateCreated -le (Get-Date).AddDays(-$Days)} $Softwaregroups | Remove-CMSoftwareUpdateGroup -Force # Finds and deletes the actual software updates files located on the server older then specified date $DeploymentPath = (Get-CMSoftwareUpdateDeploymentPackage -Name $DeploymentPackage).PkgSourcePath set-location C:\ Get-ChildItem -Path $DeploymentPath | Where-Object {$_.CreationTime -le (Get-Date).AddDays(-$Days)} | Remove-Item -Force -Recurse
Dissecting the Script
Lets go through the Config Variables first even tho i have tried to explain them briefly in the script i will talk a bit more in depth for some of them.
# Configuration Variables [String]$SitePath = "TS1:" # Name of your Site and a colon [String]$sccmserver = "SCCM1" # Name of your SCCM site server [String]$GroupNameScheme = "Client_Win10_x64*" # Software update name scheme [String]$DeploymentPackage = "Client_Win10_x64 - Monthly" # Deployment package name [String]$SCCMmodule = "D:\program Files\Microsoft Configuration Manager\AdminConsole\bin\ConfigurationManager.psd1" #Specify the path to the Configmgr PS module [Int]$Days = 90 # How many days back in time you want to delete (if 90 you will delete Software Update Groups and files older then 90 days that has the name like $GroupNameScheme you declared earlier)
$SitePath – Is used for as a path in the script so that’s why you need a Colon also
$GroupNameScheme – “Client_Win10_x64*” having a good naming scheme that differentiate is very important. Since i have created mine with Client_Win10_x64 i just add a * at the end because the ADR will add date and time to the Software group when its created so that means i will get all the groups that starts with Client_Win10_x64 later on in the script. See example below on how the groups looks like in my lab environment.
$Days = 90 # How many days back in time you want to delete (if 90 you will delete Software Update Groups and files older then 90 days that has the name like $GroupNameScheme you declared earlier)
$DeploymentPackage – “Client_Win10_x64 – Monthly” # Deployment package name, see below
Next up in the script is first to import those juicy powershell cmdlets that we can use with SCCM and then set the location to the Site server
Import-Module $SCCMmodule Set-location $SitePath
When that’s done we can finally start using them Cmdlets, we start with getting the Software Update Groups we have specified with name and also the date and then we delete them, when we do that the deployment also gets deleted.
# Finds and delete software update group and deployments older then specified date $Softwaregroups = get-cmsoftwareupdategroup -Name "$GroupNameScheme" | Where-Object {$_.DateCreated -le (Get-Date).AddDays(-$Days)} $Softwaregroups | Remove-CMSoftwareUpdateGroup -Force
And last but not least we get the source path of the Deployment package that’s associated with the Software Update Groups that we specified earlier in the $DeploymentPackage variable from there we delete the files that wore created and downloaded with the same $Date criteria as we used for getting the Software Update Groups. But to be able to delete files in the network path we specified we need to change location to C:\ or any other physical drive because if we are still in the ST1:\ environment we won’t be able to access those files. Powershell will just display an error that network path specified doesn’t exist.
# Finds and deletes the actual software updates files located on the server older then specified date $DeploymentPath = (Get-CMSoftwareUpdateDeploymentPackage -Name $DeploymentPackage).PkgSourcePath set-location C:\ Get-ChildItem -Path $DeploymentPath | Where-Object {$_.CreationTime -le (Get-Date).AddDays(-$Days)} | Remove-Item -Force -Recurse
Example
For my example i used AddMinutes instead of AddDays, this because when creating the ADR and running it makes the Software Update Group name with a date and time stamp and to be able to replicate the scenario of several groups i needed to run the ADR manually and couldn’t wait a few months for it to run 😀 but the end result is exactly the same.
Before the script ran we had 3 different Client_Win10_x64 – Monthly groups with deployments
and the Deployment Package file path was populated with all of the software update file
We run the script
And the result is as follow, the script have deleted 2 of the 3 Software Update Groups because those 2 were inside the range i declared
and the same thing follows for the Deployment Package files
So that’s all for now but i really need to warn you to NOT run this script if you aren’t 100% sure on what you are doing, you don’t wanna mess up the $Date variable so you delete everything ! Always try these kinds of things in a controlled environment first.
Cheers, Timmy
FYI… tested the script, and it went after the root of C over the package dir.
C:Scriptsclean90daydeployments.ps1
Remove-Item : Cannot remove item C:inetpublogsLogFilesW3SVC1u_ex171121.log: The process cannot access the file ‘u_ex171121.log’ because it is being used by another process.
At C:Scriptsclean90daydeployments.ps1:19 char:103
+ … ionTime -le (Get-Date).AddDays(-$Days)} | Remove-Item -Force -Recurse