Function main {
## Allows the use of -WhatIf
[CmdletBinding(SupportsShouldProcess=$True)]
param(
## Delete data older then $daystodelete
[Parameter(Mandatory=$false,ValueFromPipelineByPropertyName=$true,Position=0)]
$DaysToDelete = 5,
## LogFile path for the transcript to be written to
[Parameter(Mandatory=$false,ValueFromPipelineByPropertyName=$true,Position=1)]
$LogFile = (“C:\CMDMGMT\LOGS\”+”DiskCleanup”+’.log’),
## All verbose outputs will get logged in the transcript($logFile)
[Parameter(Mandatory=$false,ValueFromPipelineByPropertyName=$true,Position=2)]
$VerbosePreference = “Continue”,
## All errors should be withheld from the console
[Parameter(Mandatory=$false,ValueFromPipelineByPropertyName=$true,Position=3)]
$ErrorActionPreference = “SilentlyContinue”
)
## Begin the timer
$Starters = (Get-Date)
## Check $VerbosePreference variable, and turns -Verbose on
Function global:Write-Verbose ( [string]$Message ) {
if ( $VerbosePreference -ne ‘SilentlyContinue’ ) {
Write-Host “$Message” -ForegroundColor ‘Green’
}
}
Start-Transcript -Path $LogFile
Write-Verbose “Start time: $starters”
## Writes a verbose output to the screen for user information
Write-Host “Retriving current disk percent free for comparison once the script has completed. ” -NoNewline -ForegroundColor Green
## Gathers the amount of disk space used before running the script
$Before = Get-WmiObject Win32_LogicalDisk | Where-Object { $_.DriveType -eq “3” } | Select-Object SystemName,
@{ Name = “Drive” ; Expression = { ( $_.DeviceID ) } },
@{ Name = “Size (GB)” ; Expression = {“{0:N1}” -f ( $_.Size / 1gb)}},
@{ Name = “FreeSpace (GB)” ; Expression = {“{0:N1}” -f ( $_.Freespace / 1gb ) } },
@{ Name = “PercentFree” ; Expression = {“{0:P1}” -f ( $_.FreeSpace / $_.Size ) } } | Format-Table -AutoSize | Out-String
Write-Host “[DONE]” -ForegroundColor Green -BackgroundColor Black
$beforefreespace = Get-CimInstance -Class CIM_LogicalDisk | Where-Object {$_.DriveType -EQ “3” }| Select-Object @{Name=”Free Space(GB)”;Expression={$_.freespace/1gb}} |Out-String
## Stops the windows update service so that c:\windows\softwaredistribution can be cleaned up
Get-Service -Name wuauserv | Stop-Service -Force -ErrorAction SilentlyContinue -WarningAction SilentlyContinue -Verbose
Write-Host “Windows Update Service Stopped successfully” -ForegroundColor Green -BackgroundColor Black
# Verify the cleaning of CCMCache.
if (gwmi -namespace “root\ccm” -class “SMS_Client” -ea Stop)
{
write-output “Starting CCM cache Cleanup…”
# Specify Max Days For CCM Cache Entries
$MaxRetention = “5”
# Connect To Resource Manager Com Object
$SCCMClient = New-Object -ComObject UIResource.UIResourceMgr
# Get SCCM Client Cache Directory Location
$SCCMCacheDir = ($SCCMClient.GetCacheInfo().Location)
# List All Applications Due In The Future Or Currently Running
$PendingApps = $SCCMClient.GetAvailableApplications() | Where-Object { (($_.StartTime -gt (Get-Date)) -or ($_.IsCurrentlyRunning -eq “1”))}
# Create List Of Applications To Purge From Cache
$PurgeApps = $SCCMClient.GetCacheInfo().GetCacheElements() | Where-Object { ($_.ContentID -notin $PendingApps.PackageID) -and $((Test-Path -Path $_.Location) -eq $true) -and ($_.LastReferenceTime -lt (Get-Date).AddDays(- $MaxRetention)) }
# Purge Apps No Longer Required
foreach ($App in $PurgeApps)
{
$SCCMClient.GetCacheInfo().DeleteCacheElement($App.CacheElementID)
}
# Clean Up Misc Directories
$ActiveDirs = $SCCMClient.GetCacheInfo().GetCacheElements() | ForEach-Object { Write-Output $_.Location }
Get-ChildItem -Path $SCCMCacheDir | Where-Object { (($_.PsIsContainer -eq $true) -and ($_.FullName -notin $ActiveDirs)) } | Remove-Item -Recurse -Force -Verbose
}
Write-Host “Deleted the SCCMCache entries which are no longer required and older than : $MaxRetention days” -ForegroundColor Green -BackgroundColor Black
## Deletes the contents of windows software distribution.
Get-ChildItem “C:\Windows\SoftwareDistribution\*” -Recurse -Force -ErrorAction SilentlyContinue | Remove-Item -recurse -ErrorAction SilentlyContinue -Verbose
Write-Host “The Contents of Windows SoftwareDistribution have been removed successfully! ” -NoNewline -ForegroundColor Green
Write-Host “[DONE]” -ForegroundColor Green -BackgroundColor Black
## Deletes the contents of the Windows Temp folder.
Get-ChildItem “C:\Windows\Temp\*” -Recurse -Force -Verbose -ErrorAction SilentlyContinue |
Where-Object { ($_.CreationTime -lt $(Get-Date).AddDays( – $DaysToDelete)) } | Remove-Item -force -recurse -ErrorAction SilentlyContinue -Verbose
Write-host “The Contents of Windows Temp have been removed successfully! ” -NoNewline -ForegroundColor Green
Write-Host “[DONE]” -ForegroundColor Green -BackgroundColor Black
## Deletes all files and folders in user’s Temp folder older than $DaysToDelete
## Removes System and User Temp Files – lots of access denied will occur.
Get-ChildItem “C:\users\*\AppData\Local\Temp\*” -Recurse -Force -ErrorAction SilentlyContinue |
Where-Object { ($_.CreationTime -lt $(Get-Date).AddDays( – $DaysToDelete))} |
Remove-Item -force -recurse -ErrorAction SilentlyContinue -Verbose
Write-Host “The contents of `$env:TEMP have been removed successfully! ” -NoNewline -ForegroundColor Green
Write-Host “[DONE]” -ForegroundColor Green -BackgroundColor Black
## Removes all files and folders in user’s Temporary Internet Files older than $DaysToDelete
Get-ChildItem “C:\users\*\AppData\Local\Microsoft\Windows\Temporary Internet Files\*” `
-Recurse -Force -Verbose -ErrorAction SilentlyContinue |
Where-Object {($_.CreationTime -lt $(Get-Date).AddDays( – $DaysToDelete))} |
Remove-Item -Force -Recurse -ErrorAction SilentlyContinue -Verbose
Write-Host “All Temporary Internet Files have been removed successfully! ” -NoNewline -ForegroundColor Green
Write-Host “[DONE]” -ForegroundColor Green -BackgroundColor Black
## Removes System Temp Files.
## Cleans up c:\windows\temp
if (Test-Path $env:windir\Temp\) {
Remove-Item -Path “$env:windir\Temp\*” -Force -Recurse -Verbose -ErrorAction SilentlyContinue
} else {
Write-Host “C:\Windows\Temp does not exist, there is nothing to cleanup. ” -NoNewline -ForegroundColor DarkGray
Write-Host “[WARNING]” -ForegroundColor DarkYellow -BackgroundColor Black
}
## Cleans up prefetch
if (Test-Path $env:windir\Prefetch\) {
Remove-Item -Path “$env:windir\Prefetch\*” -Force -Recurse -Verbose -ErrorAction SilentlyContinue
} else {
Write-Host “$env:windir\Prefetch\ does not exist, there is nothing to cleanup. ” -NoNewline -ForegroundColor DarkGray
Write-Host “[WARNING]” -ForegroundColor DarkYellow -BackgroundColor Black
}
## Removes the hidden recycling bin.
if (Test-path ‘C:\$Recycle.Bin’){
Remove-Item ‘C:\$Recycle.Bin’ -Recurse -Force -Verbose -ErrorAction SilentlyContinue
} else {
Write-Host “C:\`$Recycle.Bin does not exist, there is nothing to cleanup. ” -NoNewline -ForegroundColor DarkGray
Write-Host “[WARNING]” -ForegroundColor DarkYellow -BackgroundColor Black
}
## Turns errors back on
$ErrorActionPreference = “Continue”
## Checks the version of PowerShell
## If PowerShell version 4 or below is installed the following will process
if ($PSVersionTable.PSVersion.Major -le 4) {
## Empties the recycling bin, the desktop recyling bin
$Recycler = (New-Object -ComObject Shell.Application).NameSpace(0xa)
$Recycler.items() | ForEach-Object {
## If PowerShell version 4 or bewlow is installed the following will process
Remove-Item -Include $_.path -Force -Recurse -Verbose
Write-Host “The recycling bin has been cleaned up successfully! ” -NoNewline -ForegroundColor Green
Write-Host “[DONE]” -ForegroundColor Green -BackgroundColor Black
}
} elseif ($PSVersionTable.PSVersion.Major -ge 5) {
## If PowerShell version 5 is running on the machine the following will process
Clear-RecycleBin -DriveLetter C:\ -Force -Verbose
Write-Host “The recycling bin has been cleaned up successfully! ” -NoNewline -ForegroundColor Green
Write-Host “[DONE]” -ForegroundColor Green -BackgroundColor Black
}
#Analyze WinSxS folder (Component Store Cleanup)
write-output “Performing Windows Update cleanup”
$CleanupimageArgs = “/online /cleanup-image /StartComponentCleanup”
Try{
$(Start-Process -FilePath C:\Windows\System32\Dism.exe -ArgumentList $CleanupImageArgs -WindowStyle Hidden -Wait -ErrorAction SilentlyContinue |wait-process )
write-output “ComponentStore Cleanup completed successfully”
}
Catch{write-output “ComponentStore Cleanup failed with error” $_.Exception.HResult, $_.Exception.Message }
# System Files Cleanup using cleanmgr:
write-output “Performing System Files Cleanup..”
$CMGReg = “HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches”
$Sub = Get-ChildItem -path $CMGReg
Foreach($path in $Sub.pspath){If(
$path -notlike “*Content Indexer Cleaner” -and
$path -notlike “*Delivery Optimization Files” -and
$path -notlike “*Device Driver Packages” -and
$path -notlike “*GameNewsFiles” -and
$path -notlike “*GameStatisticsFiles” -and
$path -notlike “*GameUpdateFiles” -and
$path -notlike “*Windows Defender” -and
$path -notlike “*DownloadsFolder” -and
$path -notlike “*Update Cleanup” -and
$path -notlike “*Offline Pages Files”){
New-ItemProperty -Path $path -Name “StateFlags0999” -PropertyType DWORD -Value ‘2’ -Force | Out-Null}}
$CleanerRunArgs = “/SAGERUN:999”
Try{
$(Start-Process -FilePath C:\Windows\System32\cleanmgr.exe -ArgumentList $CleanerRunArgs -WindowStyle Hidden -ErrorAction Stop)
write-output “System Files Cleanup completed successfully”
$global:ReturnCode = 0
}
Catch{write-output “System Files Cleanup completed with error” $_.Exception.HResult, $_.Exception.Message
$global:ReturnCode = $_.Exception.HResult}
## Sleep for 5minutes
Write-Output “Wait 5minutes for completion of Systemfiles Cleanup”
start-sleep -s 300
## Gathers disk usage after running the cleanup.
$After = Get-WmiObject Win32_LogicalDisk | Where-Object { $_.DriveType -eq “3” } | Select-Object SystemName,
@{ Name = “Drive” ; Expression = { ( $_.DeviceID ) } },
@{ Name = “Size (GB)” ; Expression = {“{0:N1}” -f ( $_.Size / 1gb)}},
@{ Name = “FreeSpace (GB)” ; Expression = {“{0:N1}” -f ( $_.Freespace / 1gb ) } },
@{ Name = “PercentFree” ; Expression = {“{0:P1}” -f ( $_.FreeSpace / $_.Size ) } } | Format-Table -AutoSize | Out-String
$afterfreespace = Get-CimInstance -Class CIM_LogicalDisk | Where-Object {$_.DriveType -EQ “3” }| Select-Object @{Name=”Free Space(GB)”;Expression={$_.freespace/1gb}} |Out-String
## Restarts wuauserv
Get-Service -Name wuauserv | Start-Service -ErrorAction SilentlyContinue -WarningAction SilentlyContinue -Verbose
## Stop timer
$Enders = (Get-Date)
Write-Verbose “End time: $Enders”
## Calculate amount of seconds your code takes to complete.
Write-Verbose “Elapsed Time: $(($Enders – $Starters).totalseconds) seconds”
## Sends hostname to the console for ticketing purposes.
Write-Host (Hostname) -ForegroundColor Green
## Sends the date and time to the console for ticketing purposes.
Write-Host (Get-Date | Select-Object -ExpandProperty DateTime) -ForegroundColor Green
## Sends the disk usage before running the cleanup script to the console for ticketing purposes.
Write-Verbose “Before: $Before”
## Sends the disk usage after running the cleanup script to the console for ticketing purposes.
Write-Verbose “After: $After”
Function WriteToCPH {
$regRoot = “HKLM:\SOFTWARE\CMD\DiskCleanup”
$installDate = (Get-Date -Format “yyyy-MM-dd HH:mm:ss”)
$objScriptTime = New-Object -ComObject WbemScripting.SWbemDateTime
$objScriptTime.SetVarDate($installDate)
$installDateDMTF = $objScriptTime.Value
## Cleans up existing registry entry of DiskCleanup
if (Test-Path $regroot) {
Remove-Item -Path “$regroot” -Force -Recurse -Verbose -ErrorAction SilentlyContinue
} else {
Write-Host “No Diskcleanup registry found” -NoNewline -ForegroundColor DarkGray
Write-Host “[WARNING]” -ForegroundColor DarkYellow -BackgroundColor Black
}
md $regRoot -Force
New-ItemProperty $regRoot -Name “InstallDate” -Value $installDate -PropertyType “String” -Force
New-ItemProperty $regRoot -Name “InstallDateDMTF” -Value $installDateDMTF -PropertyType “String” -Force
New-ItemProperty $regRoot -Name “Language” -Value “EN” -PropertyType “String” -Force
New-ItemProperty $regRoot -Name “ProductName” -Value “DiskCleanup” -PropertyType “String” -Force
New-ItemProperty $regRoot -Name “Vendor” -Value “xyz.org” -PropertyType “String” -Force
New-ItemProperty $regRoot -Name “Version” -Value “1.0” -PropertyType “String” -Force
New-ItemProperty $regRoot -Name “Status” -Value “$global:ReturnCode” -PropertyType “String” -Force
New-ItemProperty $regRoot -Name “BeforeCleanup” -Value “$beforefreespace” -PropertyType “String” -Force
New-ItemProperty $regRoot -Name “AfterCleanup” -Value “$afterfreespace” -PropertyType “String” -Force
}
WriteToCPH
## Completed Successfully!
Write-Host (Stop-Transcript) -ForegroundColor Green
}
main