<# ====================================================================== MOE GOT IT — Safe PC Cleanup ---------------------------------------------------------------------- What this does: - Deletes temporary files (yours and other user profiles) - Empties the Recycle Bin - Clears the Windows Update download cache - Clears Delivery Optimization leftover files - Clears Windows Error Reporting leftover dumps - Clears thumbnail cache and flushes DNS - Lists programs that launch at startup and lets you turn off the ones you do not want (same on/off switch Task Manager uses) What this does NOT do: - It does NOT "clean" leftover registry keys. Microsoft does not support registry cleaners; they do not speed up modern Windows and they can break programs. - It does NOT delete documents, photos, or other personal files. - It does NOT install anything. - It does NOT disable startup programs unless you type their numbers. You can read every line of this script in a browser before you run it. ====================================================================== #> $CleanupUrl = 'https://moegotit.com/techfix/script.php' function Test-MgiAdmin { $id = [Security.Principal.WindowsIdentity]::GetCurrent() $principal = New-Object Security.Principal.WindowsPrincipal($id) return $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator) } if (-not (Test-MgiAdmin)) { Write-Host "" Write-Host "Administrator permission is needed to clean system folders." -ForegroundColor Yellow Write-Host "Windows will ask you to click Yes. A new window then opens." -ForegroundColor Yellow Write-Host "" $exe = 'powershell.exe' try { $current = (Get-Process -Id $PID).Path if ($current) { $exe = $current } } catch { } if ($PSCommandPath) { Start-Process -FilePath $exe -Verb RunAs -ArgumentList "-NoProfile -ExecutionPolicy Bypass -File `"$PSCommandPath`"" } else { Start-Process -FilePath $exe -Verb RunAs -ArgumentList "-NoProfile -ExecutionPolicy Bypass -Command irm '$CleanupUrl' | iex" } exit } else { $ErrorActionPreference = 'SilentlyContinue' function Get-FolderSizeMB { param([string]$Path) if (-not (Test-Path -LiteralPath $Path)) { return 0 } $bytes = (Get-ChildItem -LiteralPath $Path -Recurse -Force -ErrorAction SilentlyContinue | Measure-Object -Property Length -Sum).Sum if ($null -eq $bytes) { return 0 } return [math]::Round($bytes / 1MB, 1) } function Clear-FolderContents { param( [string]$Path, [string]$Filter = '*' ) if (-not (Test-Path -LiteralPath $Path)) { return 0 } $before = Get-FolderSizeMB $Path Get-ChildItem -LiteralPath $Path -Filter $Filter -Force -ErrorAction SilentlyContinue | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue $after = Get-FolderSizeMB $Path $freed = [math]::Round($before - $after, 1) if ($freed -lt 0) { $freed = 0 } return $freed } $totalFreedMB = 0 Clear-Host Write-Host "" Write-Host "=====================================================" -ForegroundColor Cyan Write-Host " MOE GOT IT — Safe PC Cleanup" -ForegroundColor Cyan Write-Host "=====================================================" -ForegroundColor Cyan Write-Host " Personal files are left alone. Startup items change only if you pick them." -ForegroundColor DarkCyan Write-Host "" Write-Host "[1/7] Cleaning temporary files..." -ForegroundColor White $skipUsers = @('Public', 'Default', 'Default User', 'All Users') $userFreed = 0 foreach ($userDir in (Get-ChildItem -Path 'C:\Users' -Directory -ErrorAction SilentlyContinue)) { if ($skipUsers -contains $userDir.Name) { continue } $userFreed += Clear-FolderContents (Join-Path $userDir.FullName 'AppData\Local\Temp') $userFreed += Clear-FolderContents (Join-Path $userDir.FullName 'AppData\Local\Microsoft\Windows\INetCache') } $userFreed += Clear-FolderContents $env:TEMP $userFreed += Clear-FolderContents 'C:\Windows\Temp' $totalFreedMB += $userFreed Write-Host (" Freed about {0} MB (files in use were skipped)." -f $userFreed) -ForegroundColor Green Write-Host "[2/7] Emptying the Recycle Bin..." -ForegroundColor White Clear-RecycleBin -Force -ErrorAction SilentlyContinue Write-Host " Recycle Bin emptied." -ForegroundColor Green Write-Host "[3/7] Clearing the Windows Update download cache..." -ForegroundColor White $updatePath = 'C:\Windows\SoftwareDistribution\Download' $beforeUpdate = Get-FolderSizeMB $updatePath Stop-Service -Name wuauserv -Force -ErrorAction SilentlyContinue Get-ChildItem -LiteralPath $updatePath -Recurse -Force -ErrorAction SilentlyContinue | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue Start-Service -Name wuauserv -ErrorAction SilentlyContinue $totalFreedMB += $beforeUpdate Write-Host (" Freed about {0} MB." -f $beforeUpdate) -ForegroundColor Green Write-Host "[4/7] Clearing Delivery Optimization leftover files..." -ForegroundColor White $doPaths = @( 'C:\Windows\SoftwareDistribution\DeliveryOptimization\Cache', 'C:\Windows\ServiceProfiles\NetworkService\AppData\Local\Microsoft\Windows\DeliveryOptimization\Cache' ) $doFreed = 0 foreach ($p in $doPaths) { $doFreed += Clear-FolderContents $p } $totalFreedMB += $doFreed Write-Host (" Freed about {0} MB." -f $doFreed) -ForegroundColor Green Write-Host "[5/7] Clearing leftover error-report dumps..." -ForegroundColor White $werPaths = @( 'C:\ProgramData\Microsoft\Windows\WER\ReportQueue', 'C:\ProgramData\Microsoft\Windows\WER\ReportArchive' ) $werFreed = 0 foreach ($p in $werPaths) { $werFreed += Clear-FolderContents $p } $totalFreedMB += $werFreed Write-Host (" Freed about {0} MB." -f $werFreed) -ForegroundColor Green Write-Host "[6/7] Clearing thumbnail cache and flushing DNS..." -ForegroundColor White foreach ($userDir in (Get-ChildItem -Path 'C:\Users' -Directory -ErrorAction SilentlyContinue)) { if ($skipUsers -contains $userDir.Name) { continue } $thumbs = Join-Path $userDir.FullName 'AppData\Local\Microsoft\Windows\Explorer' if (Test-Path -LiteralPath $thumbs) { Get-ChildItem -LiteralPath $thumbs -Filter 'thumbcache_*.db' -Force -ErrorAction SilentlyContinue | Remove-Item -Force -ErrorAction SilentlyContinue } } Clear-DnsClientCache -ErrorAction SilentlyContinue Write-Host " Done." -ForegroundColor Green function Get-MgiApprovedState { param([string]$ApprovedPath, [string]$ValueName) if (-not (Test-Path -LiteralPath $ApprovedPath)) { return 'on' } try { $key = Get-Item -LiteralPath $ApprovedPath -ErrorAction Stop $val = $key.GetValue($ValueName, $null) if ($null -eq $val -or $val.Length -lt 1) { return 'on' } $flag = [int]$val[0] if ($flag -eq 3 -or $flag -eq 7) { return 'off' } } catch { } return 'on' } function Get-MgiRunKeyItems { param([string]$RunPath, [string]$ApprovedPath, [string]$Source) $list = @() if (-not (Test-Path -LiteralPath $RunPath)) { return $list } $key = Get-Item -LiteralPath $RunPath foreach ($name in $key.GetValueNames()) { if ([string]::IsNullOrWhiteSpace($name)) { continue } $list += [pscustomobject]@{ Name = $name Command = [string]$key.GetValue($name) Source = $Source ApprovedPath = $ApprovedPath ValueName = $name State = Get-MgiApprovedState $ApprovedPath $name } } return $list } function Get-MgiStartupFolderItems { param([string]$Folder, [string]$ApprovedPath, [string]$Source) $list = @() if ([string]::IsNullOrWhiteSpace($Folder) -or -not (Test-Path -LiteralPath $Folder)) { return $list } $files = Get-ChildItem -LiteralPath $Folder -File -ErrorAction SilentlyContinue | Where-Object { $_.Name -ne 'desktop.ini' -and $_.Extension -match '\.(lnk|url|exe|bat|cmd)$' } foreach ($file in $files) { $list += [pscustomobject]@{ Name = $file.BaseName Command = $file.FullName Source = $Source ApprovedPath = $ApprovedPath ValueName = $file.Name State = Get-MgiApprovedState $ApprovedPath $file.Name } } return $list } function Disable-MgiStartupItem { param($Item) $bytes = [byte[]](3, 0, 0, 0) + [BitConverter]::GetBytes([int64][DateTime]::Now.ToFileTime()) if (-not (Test-Path -LiteralPath $Item.ApprovedPath)) { New-Item -Path $Item.ApprovedPath -Force | Out-Null } New-ItemProperty -LiteralPath $Item.ApprovedPath -Name $Item.ValueName -PropertyType Binary -Value $bytes -Force -ErrorAction Stop | Out-Null } Write-Host "[7/7] Startup programs — pick any you want OFF:" -ForegroundColor White Write-Host " This uses the same on/off switch as Task Manager." -ForegroundColor DarkGray Write-Host " Nothing is turned off unless you type its number." -ForegroundColor DarkGray Write-Host "" $startupItems = @() $startupItems += @(Get-MgiRunKeyItems 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Run' 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\StartupApproved\Run' 'Your account') $startupItems += @(Get-MgiRunKeyItems 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Run' 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\StartupApproved\Run' 'This PC') $startupItems += @(Get-MgiRunKeyItems 'HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Run' 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\StartupApproved\Run32' 'This PC (32-bit)') $startupItems += @(Get-MgiStartupFolderItems ([Environment]::GetFolderPath('Startup')) 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\StartupApproved\StartupFolder' 'Your Startup folder') $startupItems += @(Get-MgiStartupFolderItems ([Environment]::GetFolderPath('CommonStartup')) 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\StartupApproved\StartupFolder' 'Shared Startup folder') $startupItems = @($startupItems | Sort-Object Name, Source) $disabledCount = 0 if ($startupItems.Count -eq 0) { Write-Host " (None found.)" -ForegroundColor Gray } else { Write-Host (" {0,-4}{1,-8}{2,-32}{3}" -f '#', 'Status', 'Program', 'Where') -ForegroundColor Cyan for ($i = 0; $i -lt $startupItems.Count; $i++) { $item = $startupItems[$i] $status = if ($item.State -eq 'off') { 'off' } else { 'ON' } $color = if ($item.State -eq 'off') { 'DarkGray' } else { 'Gray' } $label = $item.Name if ($label.Length -gt 30) { $label = $label.Substring(0, 29) + '.' } Write-Host (" {0,-4}{1,-8}{2,-32}{3}" -f ($i + 1), $status, $label, $item.Source) -ForegroundColor $color } Write-Host "" Write-Host " Type numbers to turn OFF (example: 1,3,5)." -ForegroundColor Yellow Write-Host " Press Enter to leave them as they are." -ForegroundColor Yellow $raw = Read-Host " Numbers" if ([string]::IsNullOrWhiteSpace($raw)) { Write-Host " Startup programs left as they are." -ForegroundColor DarkGray } else { $picked = @() foreach ($token in ($raw -split '[, ]+')) { if ($token -notmatch '^\d+$') { continue } $n = [int]$token if ($n -lt 1 -or $n -gt $startupItems.Count) { continue } $picked += $startupItems[$n - 1] } $picked = @($picked | Where-Object { $_.State -ne 'off' } | Sort-Object Name -Unique) if ($picked.Count -eq 0) { Write-Host " Nothing new to turn off." -ForegroundColor DarkGray } else { Write-Host "" Write-Host " Will turn OFF:" -ForegroundColor Yellow foreach ($item in $picked) { Write-Host (" - {0}" -f $item.Name) -ForegroundColor Gray } $confirm = Read-Host " Type YES to confirm" if ($confirm -eq 'YES') { foreach ($item in $picked) { try { Disable-MgiStartupItem $item $disabledCount++ Write-Host (" Off: {0}" -f $item.Name) -ForegroundColor Green } catch { Write-Host (" Could not turn off {0}." -f $item.Name) -ForegroundColor Red } } Write-Host " You can turn any of these back on in Task Manager > Startup apps." -ForegroundColor DarkGray } else { Write-Host " No startup programs were changed." -ForegroundColor DarkGray } } } } Write-Host "" Write-Host "=====================================================" -ForegroundColor Cyan Write-Host (" Finished. Freed roughly {0} MB in total." -f [math]::Round($totalFreedMB, 1)) -ForegroundColor Cyan if ($disabledCount -gt 0) { Write-Host (" Turned off {0} startup program(s)." -f $disabledCount) -ForegroundColor Cyan } else { Write-Host " No startup programs were changed." -ForegroundColor Cyan } Write-Host " Personal files were not touched." -ForegroundColor Cyan Write-Host "=====================================================" -ForegroundColor Cyan Write-Host "" Write-Host "Press Enter to close this window." Read-Host | Out-Null }