CATE.ps1


<#PSScriptInfo
 
.VERSION 3.57
 
.GUID f842f577-3f42-4cb0-91e7-97b499260a21
 
.AUTHOR Jonathan E. Brickman
 
.COMPANYNAME Ponderworthy Music
 
.COPYRIGHT (c) 2018 Jonathan E. Brickman
 
.TAGS
 
.LICENSEURI
 
.PROJECTURI
 
.ICONURI
 
.EXTERNALMODULEDEPENDENCIES
 
.REQUIREDSCRIPTS
 
.EXTERNALSCRIPTDEPENDENCIES
 
.RELEASENOTES
CATE - Clean All Temp Etc
Cleans temporary files and folders from all standard user temp folders,
system profile temp folders, and system temp folders (they are not the same!);
also clears logs, IE caches, Firefox caches, Chrome caches, Ask Partner Network data,
Adobe Flash caches, Java deployment caches, and Microsoft CryptnetURL caches.
 
.PRIVATEDATA
 
#>
 



































<#
 
.DESCRIPTION
Clean All Temp Etc - cleans temporary files and folders from all standard user and system temp folders, clears logs, and more
 
#>
 

Param()


#############################
# CATE: Clean All Temp Etc. #
#############################

#
# by Jonathan E. Brickman
#
# Cleans temp files from all user profiles and
# several other locations. Also clears log files.
#
# Copyright 2018 Jonathan E. Brickman
# https://notes.ponderworthy.com/
# This script is licensed under the 3-Clause BSD License
# https://opensource.org/licenses/BSD-3-Clause
# and is reprised at the end of this file
#

""
"Clean All Temp Etc."
""

# Self-elevate if not already elevated.

if (([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator"))
    {    
    "Running elevated; good."
    ""
    }
else {
    "Not running as elevated. Starting elevated shell." 
    Start-Process powershell -WorkingDirectory $PSScriptRoot -Verb runAs -ArgumentList "-noprofile -noexit -file $PSCommandPath" 
    return "Done. This one will now exit."
    ""
    }

# Get initial shell location.

$InitialLocation = Get-Location

# Get environment variables.

$envTEMP = [Environment]::GetEnvironmentVariable("TEMP", "Machine")
$envTMP = [Environment]::GetEnvironmentVariable("TEMP", "Machine")
$envSystemDrive = $env:SystemDrive
$envSystemRoot = $env:SystemRoot
$envProgramData = $env:ProgramData

# Get initial free disk space.

function DriveSpace {
    param( [string] $strComputer) 

    # Does the server responds to a ping (otherwise the WMI queries will fail)

    $query = "select * from win32_pingstatus where address = '$strComputer'"
    $result = Get-WmiObject -query $query
    if ($result.protocoladdress) {

        $totalFreeSpace = 0

        # Get the Disks for this computer
        $colDisks = get-wmiobject Win32_LogicalDisk -computername $strComputer -Filter "DriveType = 3"

        # For each disk calculate the free space
        foreach ($disk in $colDisks) {
            $totalFreeSpace = $totalFreeSpace + $disk.freespace
            }
        
        return $totalFreeSpace
        }
    }

function RptDriveSpace {
    param( $rawDriveSpace )

    $MBDriveSpace = [double]$rawDriveSpace / 1024000.0
    $truncatedDriveSpace = [double]([math]::Truncate($MBDriveSpace))
    $fracDriveSpace = [double]$MBDriveSpace - [double]$truncatedDriveSpace

    return "{0:N0}{1:.###}" -f $truncatedDriveSpace, $fracDriveSpace
    }

$initialFreeSpace = DriveSpace("localhost")
$strOut = RptDriveSpace( $initialFreeSpace )
$strOut = "Initial free space (all drives): " + $strOut + " megabytes."
Write-Output $strOut

# Here is an external variable to contain the "Status" text
# for progress reporting.

$reportStatus = "Working..."

# Now we set up an array containing folders to be checked for and
# cleaned out if present, for every profile.

$foldersToClean = @(
    "\Local Settings\Temp",
    "\Local Settings\Temporary Internet Files",
    "\AppData\Local\Microsoft\Windows\Temporary Internet Files",
    "\AppData\Local\Microsoft\Windows\INetCache\IE",
    "\AppData\Local\Microsoft\Windows\INetCache\Low\Content.IE5",
    "\AppData\Local\Microsoft\Windows\INetCache\Low\Flash",
    "\AppData\Local\Microsoft\Windows\INetCache\Content.Outlook",
    "\AppData\Local\Google\Chrome\User Data\Default\Cache",
    "\AppData\Local\Mozilla\Firefox\Profiles\*\cache",
    "\AppData\Local\Mozilla\Firefox\Profiles\*\cache2\entries",
    "\AppData\Local\Mozilla\Firefox\Profiles\*\thumbnails",
    "\AppData\Local\Mozilla\Firefox\Profiles\*\cookies.sqlite",
    "\AppData\Local\Mozilla\Firefox\Profiles\*\webappsstore.sqlite",
    "\AppData\Local\Mozilla\Firefox\Profiles\*\chromeappsstore.sqlite",
    "\AppData\Local\AskPartnerNetwork",
    "\Application Data\Local\Microsoft\Windows\WER",
    "\Application Data\Adobe\Flash Player\AssetCache",
    "\Application Data\Sun\Java\Deployment\cache",
    "\Application Data\Microsoft\CryptnetUrlCache"
    )

# A quasiprimitive for PowerShell-style progress reporting.

function ShowCATEProgress {
    param( [string]$currentOp )

    Write-Progress -Activity "Clean All Temp Etc" -Status $reportStatus -PercentComplete -1 -CurrentOperation $currentOp
    }

# Here's a special routine for deletes, with
# our special sauce for reporting.

function DeleteFolderContents {
    param( [string]$strFolder,
           [bool]$skipSpecial = $false )

    ShowCATEProgress ""

    # If $strFolder is not a real folder, end function
    if ( !(Test-Path $strFolder) ) {
        return
        }

    # Try to CD/CHDIR/Set-Location into the folder.
    # If cannot, return false for error.
    # This covers nonfolders.
    Try {
        Set-Location $strFolder
        }
    Catch {
        return
        }

    # Enumerate all contents and delete.
    # For some reason, try/catch did not flag permissions errors when tested.
    Get-ChildItem -path $strFolder -Force -ErrorAction SilentlyContinue | ForEach {
        ShowCATEProgress $_
        If ( $_.PSIsContainer ) {
            # Item is a folder.
            If ($skipSpecial) {
                # If $skipSpecial, attempt to remove it and everything under
                # except folders named "Low", "1", and "2".
                Try { Remove-Item $_ -Force -Recurse -Exclude "Low","1","2" -ErrorAction SilentlyContinue }
                Catch {}
                }
            else {
                # Attempt to remove it and everything under.
                Try { Remove-Item $_ -Force -Recurse -ErrorAction SilentlyContinue }
                Catch {}
                }
            } 
        else {
                # Item is not a folder.
                Try { Remove-Item $_ -Force -ErrorAction SilentlyContinue }
                Catch {}
            }
        }
    }

# Next we loop through all of the paths for all user profiles
# as recorded in the registry, and delete temp files.

# Outer loop enumerates all user profiles
$ProfileList = Get-ChildItem -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\"
$ProfileCount = $ProfileList.Count
$ProfileNumber = 1
$ProfileList | ForEach-Object {
    $profileItem = Get-ItemProperty $_.pspath
    $reportStatus = "Working on (profile " + $ProfileNumber + "/" + $ProfileCount + ") " + $profileItem.ProfileImagePath + " ..."
    $ProfileNumber += 1

    # Inner loop enumerates all folder subpaths within profiles to be cleaned
    ForEach ($folderSubpath in $foldersToClean) {
        $ToClean = $profileItem.ProfileImagePath+$folderSubpath
        If (Test-Path $ToClean) {
            # If the actual path exists, clean it
            ShowCATEProgress $ToClean
            DeleteFolderContents $ToClean
            }
        }

    # One special subpath needing TLC
    $ToClean = $profileItem.ProfileImagePath+"\AppData\Local\Temp"
    If (Test-Path $ToClean) {
        # If the actual path exists, clean it; the second parameter means skip folders named "Low", "1", or "2"
        ShowCATEProgress $ToClean
        DeleteFolderContents $ToClean $True
        }

    # Subpaths to be eliminated altogether, also present in the $foldersToClean list above
    Remove-Item "AskPartnerNetwork" -Force -Recurse -ErrorAction SilentlyContinue
    }

# Now empty certain folders

$reportStatus = "Working on other folders ..."

DeleteFolderContents ($envTEMP)

DeleteFolderContents ($envTMP)

DeleteFolderContents ($envSystemRoot + "\Temp"), $true

DeleteFolderContents ($envSystemRoot + "\system32\wbem\logs")

DeleteFolderContents ($envSystemRoot + "\system32\Debug")

DeleteFolderContents ($envSystemRoot + "\PCHEALTH\ERRORREP\UserDumps")

DeleteFolderContents ($envProgramData + "\Microsoft\Windows\WER\ReportQueue")

# Function to delete objects nonrecursively. Can handle wildcards.

function DeleteObjects {
    param( [string]$strPath  )

    ShowCATEProgress $strPath
    If ( !(Test-Path $strPath -ErrorAction SilentlyContinue) ) { return }
    Remove-Item -Path $strPath -Force -ErrorAction SilentlyContinue
    }


DeleteObjects ($envSystemRoot + "\system32\Logfiles\*\*.log")

DeleteObjects ($envSystemRoot + "\system32\Logfiles\*\*.EVM")

DeleteObjects ($envSystemRoot + "\system32\Logfiles\*\*.EVM.*")

DeleteObjects ($envSystemRoot + "\system32\Logfiles\*\*.etl")

DeleteObjects ($envSystemRoot + "\Logs\*\*.log")

DeleteObjects ($envSystemRoot + "\Logs\*.etl")

DeleteObjects ($envSystemRoot + "\inf\*.log")

DeleteObjects ($envSystemRoot + "\Prefetch\*.pf")


$finalFreeSpace = DriveSpace("localhost")
$strOut = RptDriveSpace( $finalFreeSpace )
$strOut = "Final free space (all drives): " + $strOut + " megabytes."
Write-Output $strOut

$freedSpace = $finalFreeSpace - $initialFreeSpace
$strOut = RptDriveSpace ( $freedSpace )
$strOut = "Freed " + $strOut + " megabytes."
Write-Output ""
Write-Output $strOut
Write-Output ""

Start-Sleep 3

# The 3-Clause BSD License

# SPDX short identifier: BSD-3-Clause

# Note: This license has also been called
# the AYA>A>??sA??.??oNew BSD LicenseAYA>A>??sA??,A? or AYA>A>??sA??.??oModified BSD LicenseAYA>A>??sA??,A?.
# See also the 2-clause BSD License.

# Copyright 2017 Jonathan E. Brickman

# Redistribution and use in source and binary
# forms, with or without modification, are
# permitted provided that the following conditions are met:

# 1. Redistributions of source code must retain the
# above copyright notice, this list of conditions and
# the following disclaimer.

# 2. Redistributions in binary form must reproduce the
# above copyright notice, this list of conditions and
# the following disclaimer in the documentation and/or
# other materials provided with the distribution.

# 3. Neither the name of the copyright holder nor the
# names of its contributors may be used to endorse or
# promote products derived from this software without
# specific prior written permission.

# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
# CONTRIBUTORS AYA>A>??sA??.??oAS ISAYA>A>??sA??,A? AND ANY EXPRESS OR IMPLIED WARRANTIES,
# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
# OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
# GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
# BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.