If you work with most companies there will come a time when you will need to clean out user profiles that have just too much temporary file junk in them.

Earlier this month we spent a few hours developing the script below that deletes:

  1. all of the common temp files in a user’s profile
    • “AppData\Local\Temp”,
      “AppData\Local\Microsoft\Windows\INetCache”,
      “AppData\Local\Microsoft\Windows\INetCookies”,
      “AppData\Local\Microsoft\Windows\Temporary Internet Files”,
      “AppData\Local\Microsoft\Windows\Explorer”,
      “AppData\Local\Temp\Low”,
      “AppData\Local\Google\Chrome\User Data\Default\Cache”,
      “AppData\Local\Mozilla\Firefox\Profiles\*\cache2” # Firefox cache
      “AppData\Local\Microsoft\Edge\User Data\Default\Cache”, # Edge cache
      “AppData\Local\Microsoft\Edge\User Data\Default\Code Cache”, # Edge code cache
      “AppData\Local\Microsoft\Edge\User Data\Default\GPUCache” # Edge GPU cache
  2. any files in their DOWNLOADS folder that are older than 8 days
  3. all RECYCLE BINs
powershell script to clean up user profiles

Just run this script in an elevated Power Shell and you may get back a considerable amount of disk space as well as clearing up many odd user problems:


# Log off disconnected users
Get-WmiObject -Class Win32_LogonSession | Where-Object { $_.LogonType -eq 10 } | ForEach-Object {
    logoff $_.LogonId
}

# Get the current user
$currentUser = [System.Security.Principal.WindowsIdentity]::GetCurrent().Name

# Get all user profiles except the default profile
$profiles = Get-WmiObject -Class Win32_UserProfile | Where-Object { $_.Special -eq $false }

# Grant access to each user profile
foreach ($profile in $profiles) {
    $profilePath = $profile.LocalPath
    Write-Host "Granting access to $profilePath for $currentUser"
    $acl = Get-Acl $profilePath
    $accessRule = New-Object System.Security.AccessControl.FileSystemAccessRule($currentUser, "FullControl", "ContainerInherit,ObjectInherit", "None", "Allow")
    $acl.SetAccessRule($accessRule)
    Set-Acl $profilePath $acl
}

Write-Host "Access granted to all user profiles for $currentUser"

# Initialize total recovered space variable
$totalRecoveredSpace = 0

# Delete temp folders and old downloads for each user profile, and calculate recovered space
$tempFolders = @(
    "AppData\Local\Temp",
    "AppData\Local\Microsoft\Windows\INetCache",
    "AppData\Local\Microsoft\Windows\INetCookies",
    "AppData\Local\Microsoft\Windows\Temporary Internet Files",
    "AppData\Local\Microsoft\Windows\Explorer",
    "AppData\Local\Temp\Low",
    "AppData\Local\Google\Chrome\User Data\Default\Cache",
    "AppData\Local\Mozilla\Firefox\Profiles\*\cache2" # Firefox cache
    "AppData\Local\Microsoft\Edge\User Data\Default\Cache", # Edge cache
    "AppData\Local\Microsoft\Edge\User Data\Default\Code Cache", # Edge code cache
    "AppData\Local\Microsoft\Edge\User Data\Default\GPUCache" # Edge GPU cache
)

foreach ($profile in $profiles) {
    $profilePath = $profile.LocalPath
    $userName = [System.IO.Path]::GetFileName($profilePath) # Extract the username from the profile path
    $userRecoveredSpace = 0
    Write-Host "Processing user: $userName"

    foreach ($folder in $tempFolders) {
        $fullPath = Join-Path -Path $profilePath -ChildPath $folder
        if (Test-Path $fullPath) {
            $folderItems = Get-ChildItem -Path $fullPath -Recurse -Force -ErrorAction SilentlyContinue
            $fileItems = $folderItems | Where-Object { -not $_.PsIsContainer }
            $folderSizeBefore = ($fileItems | Measure-Object -Property Length -Sum).Sum
            $folderItems | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue
            $folderSizeAfter = (Get-ChildItem -Path $fullPath -File -Recurse -Force -ErrorAction SilentlyContinue | Measure-Object -Property Length -Sum).Sum
            $recoveredSpace = $folderSizeBefore - $folderSizeAfter
            $userRecoveredSpace += $recoveredSpace
            $totalRecoveredSpace += $recoveredSpace
        }
    }

    # Delete old files and folders in the Downloads folder
    $downloadsPath = Join-Path -Path $profilePath -ChildPath "Downloads"
    if (Test-Path $downloadsPath) {
        $oldItems = Get-ChildItem -Path $downloadsPath -Recurse -Force -ErrorAction SilentlyContinue | Where-Object { $_.LastWriteTime -lt (Get-Date).AddDays(-8) }
        $downloadsSizeBefore = ($oldItems | Measure-Object -Property Length -Sum).Sum
        $oldItems | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue
        $downloadsSizeAfter = (Get-ChildItem -Path $downloadsPath -File -Recurse -Force -ErrorAction SilentlyContinue | Measure-Object -Property Length -Sum).Sum
        $downloadsRecoveredSpace = $downloadsSizeBefore - $downloadsSizeAfter
        $userRecoveredSpace += $downloadsRecoveredSpace
        $totalRecoveredSpace += $downloadsRecoveredSpace
    }

    Write-Host "User ${userName}: Recovered space: ${userRecoveredSpace} bytes"
}

# Empty all users' recycle bins
$recycleBinPath = "C:\$RECYCLE.BIN"
if (Test-Path $recycleBinPath) {
    Get-ChildItem -Path $recycleBinPath -Recurse -Force -ErrorAction SilentlyContinue | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue
    Write-Host "Emptied all users' recycle bins"
}

# Report total recovered space
Write-Host "Total recovered space: ${totalRecoveredSpace} bytes"


0 Comments

Leave a Reply

Avatar placeholder

Your email address will not be published. Required fields are marked *