Automated Windows Clean-up PowerShell function.

Discussion in 'Scripting' started by GodHand, Jul 11, 2018.

  1. GodHand

    GodHand MDL Senior Member

    Jul 15, 2016
    445
    516
    10
    #1 GodHand, Jul 11, 2018
    Last edited: Aug 1, 2019
    **This has been updated. Its output it different, and is entirely verbose, outputting all its results and removals to a transcript log that is regenerated each time its run similar to Windows' logs.

    Also re-arranged how some process blocks run.**

    This is a fairly simple Windows Clean-up function I will adjust and use on both sysprep and live installations. I have added the bulk of the default folders and directories that can accumulate a sizable amount of junk. One can simply add, remove or change the directories that are cleaned-up to incorporate custom or additional folders to clean.

    What it does:
    - Measures the total size of all contents within a folder/directory that's being cleaned.
    - Performs the actual cleaning process, returning the total sum of all contents removed.
    - Enables all Clean-up Manager options by adding the StateFlags registry property to each key present.
    - Runs the Clean-up Manager process as a .NET object class to prevent its GUI output, thus not requiring you to check boxes for clean-up.
    - Disables all Clean-up Manager options previously added by removing the StateFlags registry property..
    - Returns a PSCustomObject showing combined clean-up results.

    The default download directory is NOT included in the clean-up process since many users rely on this directory to save downloaded data.

    Code:
    Function Start-WindowsCleanup
    {
    <#
       .SYNOPSIS
           Clean-up temporary files and folders and reclaim disk space.
     
       .DESCRIPTION
           This functions cleans-up temporary Windows files, folders and directories.
           This function runs the Windows Disk Clean-up Manager by enabling all of its available clean-up options within the registry and then running the CleanMgr.exe as a .NET process.
           It enables all options by adding the StateFlags registry property name to the VolumeCache registry keys.
           These options are then disabled, after CleanMgr.exe has run, to ensure no other programs can utilize its features without permission.
     
       .PARAMETER StateFlags
           An optional integer for the StateFlags registry property name in case a specific value is required.
           The default value is 1.
     
       .EXAMPLE
           PS C:\> Start-WindowsCleanup
           PS C:\> Start-WindowsCleanup -StateFlags 1234
     
       .NOTES
           The Download folder is not included in the clean-up with Windows Disk Clean-up Manager to make sure no downloaded files are removed without explicit permission.
    #>
       [CmdletBinding(ConfirmImpact = 'High',
                      SupportsShouldProcess = $true)]
       Param
       (
           [Parameter(Mandatory = $false,
                      HelpMessage = 'An optional integer for the StateFlags registry property.')]
           [ValidateRange(1, 9999)]
           [int]$StateFlags = 5432
       )
     
       Begin
       {
           $PropertyName = "StateFlags{0:D4}" -f $StateFlags
           $ReportLog = Join-Path -Path "$Env:SystemRoot\Temp" -ChildPath "Start-WindowsCleanup_$(Get-Date -Format "MM-dd-yyyy").log"
           Start-Transcript -Path $ReportLog
           Function Clear-Item
           {
               [CmdletBinding()]
               Param
               (
                   [string]$Path,
                   [switch]$Remove
               )
               If ($Remove.IsPresent) { Remove-Item -Path $($Path) -Recurse -Force -Verbose -ErrorAction SilentlyContinue }
               Else { Get-ChildItem -Path $($Path) -Recurse -Force -ErrorAction SilentlyContinue | Remove-Item -Recurse -Force -Verbose -Erroraction SilentlyContinue }
           }
       }
       Process
       {
           If ($PSCmdlet.ShouldProcess("$Env:COMPUTERNAME, All distribution, logging and temporary content will be lost"))
           {
               Clear-Host
               $PreClean = Get-CimInstance -ClassName Win32_LogicalDisk | Where-Object -Property DriveType -EQ 3 | Select-Object -Property 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
               Clear-Item -Path "$Env:TEMP\*"
               Clear-Item -Path "$Env:SystemRoot\Temp\*"
               Clear-Item -Path "C:\Users\*\AppData\Local\Temp\*"
               Clear-Item -Path "$Env:SystemRoot\SoftwareDistribution\Download\*"
               Clear-Item -Path "C:\Users\*\AppData\Local\Microsoft\Windows\Temporary Internet Files\*"
               Clear-Item -Path "C:\Users\*\AppData\Local\Microsoft\Windows\IECompatCache\*"
               Clear-Item -Path "C:\Users\*\AppData\Local\Microsoft\Windows\IECompatUaCache\*"
               Clear-Item -Path "C:\Users\*\AppData\Local\Microsoft\Windows\IEDownloadHistory\*"
               Clear-Item -Path "C:\Users\*\AppData\Local\Microsoft\Windows\INetCache\*"
               Clear-Item -Path "C:\Users\*\AppData\Local\Microsoft\Windows\INetCookies\*"
               Clear-Item -Path "C:\Users\*\AppData\Local\Microsoft\Terminal Server Client\Cache\*"
               Clear-Item -Path "C:\Users\*\AppData\Local\Microsoft\Windows\WER\*"
               Clear-Item -Path "$Env:ProgramData\Microsoft\Windows\WER\*"
               Clear-Item -Path "$Env:SystemRoot\Logs\*"
               Clear-Item -Path "$Env:SystemRoot\WinSxS\ManifestCache\*"
               Clear-Item -Path "$Env:SystemDrive\swtools\*"
               Clear-Item -Path "$Env:SystemDrive\swsetup\*"
               Clear-Item -Path "$Env:SystemRoot\drivers\*"
               Clear-Item -Path "$Env:SystemDrive\Users\Administrator\Downloads\*"
               Clear-Item -Path "$Env:SystemRoot\minidump\*"
               Clear-Item -Path "$Env:SystemRoot\Prefetch\*"
               Clear-Item -Path "$Env:HOMEDRIVE\inetpub\logs\LogFiles\*"
               Clear-Item -Path "$Env:HOMEDRIVE\PerfLogs\*"
               Clear-Item -Path "$Env:HOMEDRIVE\Intel\*"
               Clear-Item -Path "$Env:HOMEDRIVE\Config.Msi" -Remove
               Clear-Item -Path "$Env:SystemRoot\*.log" -Remove
               Clear-Item -Path "$Env:SystemRoot\Logs\CBS\*.log" -Remove
               Clear-Item -Path "$Env:SystemRoot\Logs\DISM\*.log*" -Remove
               Clear-Item -Path "$Env:SystemRoot\memory.dmp" -Remove
               If ($PSVersionTable.PSVersion.Major -lt 5) { (New-Object -ComObject Shell.Application).NameSpace(0xA).Items() | ForEach-Object -Process { Remove-Item -Path $_.Path -Force -Recurse -Verbose -ErrorAction SilentlyContinue } }
               Else { Clear-RecycleBin -Force -Confirm:$false -Verbose -ErrorAction SilentlyContinue }
               Remove-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Applets\Regedit" -Name LastKey -Force -ErrorAction SilentlyContinue
               Get-ChildItem -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches" -Exclude "Downloaded Program Files", "DownloadsFolder" -ErrorAction SilentlyContinue | ForEach-Object { Set-ItemProperty -Path $($_.PsPath) -Name $PropertyName -Value 2 -Force -ErrorAction SilentlyContinue }
               $ProcessInfo = New-Object -TypeName System.Diagnostics.ProcessStartInfo
               $ProcessInfo.FileName = "$Env:SystemRoot\System32\cleanmgr.exe"
               $ProcessInfo.Arguments = '/SAGERUN:{0}' -f $StateFlags.ToString()
               $ProcessInfo.CreateNoWindow = $true
               $Process = New-Object -TypeName System.Diagnostics.Process
               $Process.StartInfo = $ProcessInfo
               [void]$Process.Start()
               $Process.WaitForExit()
               Get-ChildItem -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches" -Exclude "Downloaded Program Files", "DownloadsFolder" -ErrorAction SilentlyContinue | ForEach-Object { Remove-ItemProperty -Path $($_.PsPath) -Name $PropertyName -Force -ErrorAction SilentlyContinue }
               $PostClean = Get-CimInstance -ClassName Win32_LogicalDisk | Where-Object -Property DriveType -EQ 3 | Select-Object -Property 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-Output "`n`n`t`t`tBefore Clean-up:`n$PreClean" -Verbose
               Write-Output "`t`t`tAfter Clean-up:`n$PostClean" -Verbose
           }
       }
       End
       {
           Stop-Transcript
       }
    }
    
    To run, you can copy and paste the code into a PowerShell console/ISE, or right-click and run-as Administrator.
     
  2. tehhunter

    tehhunter MDL Novice

    Aug 9, 2012
    18
    4
    0
    thank you excellent