Files
Powershell/PCRemediation/Invoke-PCRemediation.ps1
T
Kevin Simmons 78957bf722 Fix remote remediation to use proper system paths
- Clear-TempFiles: Uses CIM to get system root and enumerate files by date
- Clear-WerDumps: Uses CIM to get system root and program data paths
- Reset-NetworkStack: Uses CIM to get system root for ipconfig/netsh
- Clear-WindowsUpdateFiles: Uses CIM to get system root for update paths
- Clear-BrowserCaches: Uses CIM to get system root for user profile paths
- All remote operations now use proper system paths from remote machine
2026-10-04 15:26:20 -05:00

748 lines
33 KiB
PowerShell

<#=================================================================================
PC Remediation & Cleanup - Remote Edition
=================================================================================
.SYNOPSIS
Performs system cleanup, maintenance, and service remediation on local or remote Windows computers.
.DESCRIPTION
This script provides targeted manual remediation tools to free up disk space, restart stopped
critical services, clear update caches, purge temporary logs, handle pending reboot flags,
clean browser caches, and report disk space changes.
Compatible with Windows PowerShell 5.1 and supports local/remote CIM sessions (DCOM and WinRM).
.PARAMETER ComputerName
Specifies target computer(s). Default: Localhost.
.PARAMETER Credential
PSCredential for remote connections.
.PARAMETER LogToFile
Logs output to Desktop\PCRemediation.
.PARAMETER LogPath
Specifies custom log path. Default: Desktop\PCRemediation.
.PARAMETER Silent
Runs script without interactive prompts or console output.
.PARAMETER ExportHTML
Generates an HTML report of remediation tasks performed.
.PARAMETER RunAllRemediations
Executes all cleanup and maintenance tasks without interactive prompts.
.PARAMETER TempFileAgeDays
Specifies the minimum age (in days) of temporary files to delete. Default: 3 days.
.PARAMETER Help
Displays detailed help information.
.EXAMPLE
.\Invoke-PCRemediation.ps1
Runs interactive remediation menu on the local computer.
.EXAMPLE
.\Invoke-PCRemediation.ps1 -ComputerName PC01,PC02 -RunAllRemediations -LogToFile
Executes all remediation tasks on remote computers non-interactively and logs results.
.EXAMPLE
.\Invoke-PCRemediation.ps1 -ComputerName PC03 -Credential (Get-Credential) -ExportHTML
Runs all remediations on remote computer with credentials and exports HTML report.
.EXAMPLE
.\Invoke-PCRemediation.ps1 -ComputerName PC04 -Silent
Runs all remediations silently on remote computer.
.EXAMPLE
.\Invoke-PCRemediation.ps1 -Help
Displays detailed help information.
.AUTHOR
Kevin Simmons
================================================================================ #>
param (
[Parameter(Mandatory=$false)]
[string[]]$ComputerName,
[Parameter(Mandatory=$false)]
[pscredential]$Credential,
[Parameter(Mandatory=$false)]
[switch]$LogToFile,
[Parameter(Mandatory=$false)]
[string]$LogPath,
[Parameter(Mandatory=$false)]
[switch]$Silent,
[Parameter(Mandatory=$false)]
[switch]$ExportHTML,
[Parameter(Mandatory=$false)]
[switch]$RunAllRemediations,
[Parameter(Mandatory=$false)]
[int]$TempFileAgeDays = 3,
[Parameter(Mandatory=$false)]
[switch]$Help
)
if ($Help) {
Get-Help $MyInvocation.MyCommand.Path -Detailed
exit
}
if (-not $LogPath) {
$LogPath = "$([Environment]::GetFolderPath('Desktop'))\PCRemediation"
}
$IsLocal = (-not $ComputerName) -or ($ComputerName -contains $env:COMPUTERNAME)
if ($IsLocal) {
$logFile = "$LogPath\PCRemediation_$(Get-Date -Format 'yyyyMMdd_HHmmss').log"
} else {
$logFile = "$LogPath\PCRemediation_$(Get-Date -Format 'yyyyMMdd_HHmmss')_$(($ComputerName -join '_')).log"
}
$htmlReportFile = "$LogPath\PCRemediation_$(Get-Date -Format 'yyyyMMdd_HHmmss').html"
$htmlReport = $null
if ($ExportHTML) {
$htmlReport = @"
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>PC Remediation Report</title>
<style>
body { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; margin: 0; padding: 20px; background-color: #f0f0f0; color: #333; }
.container { max-width: 1000px; margin: 0 auto; background-color: #f8f8f8; padding: 20px; border-radius: 8px; box-shadow: 0 2px 5px rgba(0,0,0,0.1); }
h1 { color: #0066cc; padding-bottom: 10px; border-bottom: 1px solid #ccc; }
h2 { color: #0066cc; margin-top: 25px; }
.report-meta { background-color: #e8f0f8; padding: 10px; border-radius: 5px; margin-bottom: 20px; }
.good { color: #2e8b57; font-weight: bold; }
.warning { color: #ff9900; font-weight: bold; }
.critical { color: #cc3300; font-weight: bold; }
</style>
</head>
<body>
<div class="container">
<h1>PC Remediation Report</h1>
<div class="report-meta">
<p><strong>System:</strong> $env:COMPUTERNAME</p>
<p><strong>User:</strong> $env:USERNAME</p>
<p><strong>Date:</strong> $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')</p>
</div>
"@
}
function Write-ColorOutput {
param (
[Parameter(Mandatory=$true)]
[string]$Message,
[Parameter(Mandatory=$false)]
[string]$ForegroundColor = "White",
[Parameter(Mandatory=$false)]
[string]$StatusLevel = "Info",
[Parameter(Mandatory=$false)]
[string]$TargetComputer = $env:COMPUTERNAME
)
if (-not $Silent) {
Write-Host $Message -ForegroundColor $ForegroundColor
}
if ($LogToFile) {
if (-not (Test-Path -Path $LogPath)) {
New-Item -Path $LogPath -ItemType Directory -Force | Out-Null
}
$timestamp = Get-Date -Format 'yyyy-MM-dd HH:mm:ss'
"$timestamp [$TargetComputer] - $Message" | Out-File -FilePath $logFile -Append
}
if ($ExportHTML) {
$cssClass = "info"
if ($StatusLevel -eq "Warning") { $cssClass = "warning" }
if ($StatusLevel -eq "Critical") { $cssClass = "critical" }
if ($StatusLevel -eq "Good") { $cssClass = "good" }
$script:htmlReport += "<p class='$cssClass'>[$TargetComputer] $Message</p>"
}
}
function Get-CimSessionForComputer {
param (
[Parameter(Mandatory=$true)][string]$TargetComputer,
[Parameter(Mandatory=$false)][pscredential]$Credential
)
$sessionOptions = New-CimSessionOption -Protocol Wsman
try {
return New-CimSession -ComputerName $TargetComputer -SessionOption $sessionOptions -Credential $Credential -ErrorAction Stop
} catch {
$sessionOptions = New-CimSessionOption -Protocol Dcom
try {
return New-CimSession -ComputerName $TargetComputer -SessionOption $sessionOptions -Credential $Credential -ErrorAction Stop
} catch {
Write-ColorOutput "Failed connection to ${TargetComputer}: $_" "Red" "Critical" $TargetComputer
return $null
}
}
}
function Show-Banner {
param ([string]$TargetComputer = $env:COMPUTERNAME)
if (-not $Silent) {
Clear-Host
Write-Host "=======================================" -ForegroundColor Cyan
Write-Host " ENHANCED PC REMEDIATION " -ForegroundColor Cyan
Write-Host "=======================================" -ForegroundColor Cyan
Write-Host "System: $TargetComputer" -ForegroundColor Cyan
Write-Host "User: $env:USERNAME" -ForegroundColor Cyan
Write-Host "Date: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')" -ForegroundColor Cyan
Write-Host "=======================================" -ForegroundColor Cyan
}
}
function Show-Menu {
if (-not $Silent) {
Write-Host "`nSelect Remediation Action:" -ForegroundColor Yellow
Write-Host "1. Clear Windows Update Download Cache" -ForegroundColor White
Write-Host "2. Purge System & User Temp Files ($script:TempFileAgeDays+ days old)" -ForegroundColor White
Write-Host "3. Clear Windows Error Reporting (WER) Dumps" -ForegroundColor White
Write-Host "4. Flush DNS Cache & Reset Network Interfaces" -ForegroundColor White
Write-Host "5. Restart Automatic Services That Are Stopped" -ForegroundColor White
Write-Host "6. Empty Recycle Bin (All Users)" -ForegroundColor White
Write-Host "7. Run Component Store Cleanup (DISM)" -ForegroundColor White
Write-Host "8. Run Disk Cleanup (cleanmgr)" -ForegroundColor White
Write-Host "9. Clear Browser Caches" -ForegroundColor White
Write-Host "10. Execute Full System Remediation (All Items)" -ForegroundColor Green
Write-Host "Q. Quit" -ForegroundColor Red
}
}
function Clear-WindowsUpdateCache {
param ([string]$TargetComputer = $env:COMPUTERNAME, [Microsoft.Management.Infrastructure.CimSession]$CimSession = $null)
Write-ColorOutput "`nClearing Windows Update Cache..." "Yellow" "Info" $TargetComputer
try {
if (-not $CimSession -and $TargetComputer -eq $env:COMPUTERNAME) {
Stop-Service -Name "wuauserv", "bits" -Force -ErrorAction SilentlyContinue
$cachePath = "$env:SystemRoot\SoftwareDistribution\Download\*"
Remove-Item -Path $cachePath -Recurse -Force -ErrorAction SilentlyContinue
Start-Service -Name "wuauserv", "bits" -ErrorAction SilentlyContinue
} else {
Invoke-CimMethod -CimSession $CimSession -ClassName Win32_Process -MethodName Create -Arguments @{
CommandLine = 'cmd.exe /c net stop wuauserv & net stop bits & del /f /s /q %systemroot%\SoftwareDistribution\Download\* & net start wuauserv & net start bits'
} | Out-Null
}
Write-ColorOutput "Windows Update cache successfully purged." "Green" "Good" $TargetComputer
} catch {
Write-ColorOutput "Failed to clear Windows Update cache: $_" "Red" "Critical" $TargetComputer
}
}
function Clear-TempFiles {
param ([string]$TargetComputer = $env:COMPUTERNAME, [Microsoft.Management.Infrastructure.CimSession]$CimSession = $null, [int]$MaxAgeDays = $script:TempFileAgeDays)
Write-ColorOutput "`nPurging Temporary Files (older than $MaxAgeDays days)..." "Yellow" "Info" $TargetComputer
try {
if (-not $CimSession -and $TargetComputer -eq $env:COMPUTERNAME) {
$tempPaths = @(
"$env:SystemRoot\Temp",
"$env:LOCALAPPDATA\Temp"
)
foreach ($path in $tempPaths) {
if (Test-Path $path) {
Get-ChildItem -Path $path -Recurse -Force -ErrorAction SilentlyContinue |
Where-Object { $_.LastWriteTime -lt (Get-Date).AddDays(-$MaxAgeDays) } |
Remove-Item -Recurse -Force -ErrorAction SilentlyContinue
}
}
$userTempPaths = Get-ChildItem -Path "C:\Users" -Directory -ErrorAction SilentlyContinue |
ForEach-Object { "$($_.FullName)\AppData\Local\Temp" }
foreach ($path in $userTempPaths) {
if (Test-Path $path) {
Get-ChildItem -Path $path -Recurse -Force -ErrorAction SilentlyContinue |
Where-Object { $_.LastWriteTime -lt (Get-Date).AddDays(-$MaxAgeDays) } |
Remove-Item -Recurse -Force -ErrorAction SilentlyContinue
}
}
} else {
$systemRoot = (Get-CimInstance -ClassName Win32_OperatingSystem -CimSession $CimSession).SystemRoot
$maxAge = (Get-Date).AddDays(-$MaxAgeDays)
$tempDirs = @(
"$systemRoot\Temp",
"$systemRoot\System32\Temp"
)
foreach ($dir in $tempDirs) {
$files = Get-CimInstance -ClassName CIM_DataFile -CimSession $CimSession -Filter "Path='$($dir -replace '\\', '\\')\\' AND LastWriteTime < '$($maxAge.ToString('yyyyMMddHHmmss.ffffff+000))'" -ErrorAction SilentlyContinue
foreach ($file in $files) {
$file | Invoke-CimMethod -MethodName Delete -ErrorAction SilentlyContinue | Out-Null
}
}
$userDirs = Get-CimInstance -ClassName Win32_Directory -CimSession $CimSession -Filter "Name LIKE '%\\AppData\\Local\\Temp'" -ErrorAction SilentlyContinue
foreach ($dir in $userDirs) {
$files = Get-CimInstance -ClassName CIM_DataFile -CimSession $CimSession -Filter "Directory='$($dir.Name -replace '\\', '\\')' AND LastWriteTime < '$($maxAge.ToString('yyyyMMddHHmmss.ffffff+000))'" -ErrorAction SilentlyContinue
foreach ($file in $files) {
$file | Invoke-CimMethod -MethodName Delete -ErrorAction SilentlyContinue | Out-Null
}
}
}
Write-ColorOutput "System and user temporary files purged." "Green" "Good" $TargetComputer
} catch {
Write-ColorOutput "Failed to purge temp files: $_" "Red" "Critical" $TargetComputer
}
}
function Clear-WerDumps {
param ([string]$TargetComputer = $env:COMPUTERNAME, [Microsoft.Management.Infrastructure.CimSession]$CimSession = $null)
Write-ColorOutput "`nClearing Windows Error Reporting (WER) Dumps..." "Yellow" "Info" $TargetComputer
try {
if (-not $CimSession -and $TargetComputer -eq $env:COMPUTERNAME) {
$werPaths = @(
"$env:ProgramData\Microsoft\Windows\WER\*",
"$env:LOCALAPPDATA\CrashDumps\*"
)
foreach ($path in $werPaths) {
Remove-Item -Path $path -Recurse -Force -ErrorAction Stop
}
} else {
$systemRoot = (Get-CimInstance -ClassName Win32_OperatingSystem -CimSession $CimSession).SystemRoot
$programData = (Get-CimInstance -ClassName Win32_Environment -CimSession $CimSession -Filter "UserName='<SYSTEM>' AND Name='ProgramData'").VariableValue
$werDirs = @(
"$programData\Microsoft\Windows\WER\ReportQueue",
"$programData\Microsoft\Windows\WER\ReportArchive",
"$systemRoot\System32\winevt\Logs"
)
foreach ($dir in $werDirs) {
$files = Get-CimInstance -ClassName CIM_DataFile -CimSession $CimSession -Filter "Path='$($dir -replace '\\', '\\')\\' OR Path LIKE '$($dir -replace '\\', '\\')\\%'" -ErrorAction SilentlyContinue
foreach ($file in $files) {
$file | Invoke-CimMethod -MethodName Delete -ErrorAction SilentlyContinue | Out-Null
}
}
}
Write-ColorOutput "WER Crash Dumps cleared." "Green" "Good" $TargetComputer
} catch {
Write-ColorOutput "Failed to clear WER Dumps: $_" "Red" "Critical" $TargetComputer
}
}
function Reset-NetworkStack {
param ([string]$TargetComputer = $env:COMPUTERNAME, [Microsoft.Management.Infrastructure.CimSession]$CimSession = $null)
Write-ColorOutput "`nFlushing DNS Cache and Resetting Network Stack..." "Yellow" "Info" $TargetComputer
try {
if (-not $CimSession -and $TargetComputer -eq $env:COMPUTERNAME) {
Clear-DnsClientCache
ipconfig /flushdns | Out-Null
} else {
$os = Get-CimInstance -ClassName Win32_OperatingSystem -CimSession $CimSession
$systemRoot = $os.SystemRoot
$scriptBlock = @"
`$systemRoot = '$systemRoot'
& "`$systemRoot\System32\ipconfig.exe" /flushdns
& "`$systemRoot\System32\netsh.exe" int ip reset
& "`$systemRoot\System32\netsh.exe" winsock reset
"@
Invoke-CimMethod -CimSession $CimSession -ClassName Win32_Process -MethodName Create -Arguments @{
CommandLine = "powershell.exe -Command `$scriptBlock"
} | Out-Null
}
Write-ColorOutput "DNS Cache successfully flushed." "Green" "Good" $TargetComputer
} catch {
Write-ColorOutput "Failed to reset network stack: $_" "Red" "Critical" $TargetComputer
}
}
function Repair-StoppedAutomaticServices {
param ([string]$TargetComputer = $env:COMPUTERNAME, [Microsoft.Management.Infrastructure.CimSession]$CimSession = $null)
Write-ColorOutput "`nRestarting Stopped Automatic Services..." "Yellow" "Info" $TargetComputer
try {
if (-not $CimSession -and $TargetComputer -eq $env:COMPUTERNAME) {
$stoppedServices = Get-Service | Where-Object { $_.StartType -eq "Automatic" -and $_.Status -ne "Running" -and $_.Name -notmatch "gupdate|RemoteRegistry" }
foreach ($svc in $stoppedServices) {
Start-Service -Name $svc.Name -ErrorAction SilentlyContinue
Write-ColorOutput " Attempted start on service: $($svc.DisplayName)" "White" "Info" $TargetComputer
}
} else {
$stoppedCimServices = Get-CimInstance -ClassName Win32_Service -CimSession $CimSession |
Where-Object { $_.StartMode -eq "Auto" -and $_.State -ne "Running" -and $_.Name -notmatch "gupdate|RemoteRegistry" }
foreach ($svc in $stoppedCimServices) {
Invoke-CimMethod -InputObject $svc -MethodName "StartService" | Out-Null
Write-ColorOutput " Attempted start on remote service: $($svc.Name)" "White" "Info" $TargetComputer
}
}
Write-ColorOutput "Automatic service repair cycle complete." "Green" "Good" $TargetComputer
} catch {
Write-ColorOutput "Failed to restart automatic services: $_" "Red" "Critical" $TargetComputer
}
}
function Clear-RecycleBinFiles {
param ([string]$TargetComputer = $env:COMPUTERNAME, [Microsoft.Management.Infrastructure.CimSession]$CimSession = $null)
Write-ColorOutput "`nEmptying Recycle Bin (All Users)..." "Yellow" "Info" $TargetComputer
try {
if (-not $CimSession -and $TargetComputer -eq $env:COMPUTERNAME) {
$sids = Get-ChildItem -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\BitBucket\Volume" -ErrorAction SilentlyContinue |
ForEach-Object { $_.PSChildName }
foreach ($sid in $sids) {
$path = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\BitBucket\Volume\$sid"
if (Test-Path $path) {
Get-ChildItem -Path $path -Recurse -ErrorAction SilentlyContinue |
Remove-Item -Recurse -Force -ErrorAction SilentlyContinue
}
}
Clear-RecycleBin -Force -ErrorAction SilentlyContinue
} else {
$systemRoot = (Get-CimInstance -ClassName Win32_OperatingSystem -CimSession $CimSession).SystemRoot
$scriptBlock = @"
`$systemRoot = '$systemRoot'
`$sids = Get-ChildItem -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\BitBucket\Volume" -ErrorAction SilentlyContinue |
ForEach-Object { `$_.PSChildName }
foreach (`$sid in `$sids) {
`$path = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\BitBucket\Volume\$sid"
if (Test-Path `$path) {
Get-ChildItem -Path `$path -Recurse -ErrorAction SilentlyContinue |
Remove-Item -Recurse -Force -ErrorAction SilentlyContinue
}
}
Clear-RecycleBin -Force -ErrorAction SilentlyContinue
"@
Invoke-CimMethod -CimSession $CimSession -ClassName Win32_Process -MethodName Create -Arguments @{
CommandLine = "powershell.exe -Command `$scriptBlock"
} | Out-Null
}
Write-ColorOutput "Recycle Bin emptied for all users." "Green" "Good" $TargetComputer
} catch {
Write-ColorOutput "Failed to empty Recycle Bin: $_" "Red" "Critical" $TargetComputer
}
}
function Invoke-DismCleanup {
param ([string]$TargetComputer = $env:COMPUTERNAME, [Microsoft.Management.Infrastructure.CimSession]$CimSession = $null)
Write-ColorOutput "`nRunning DISM Component Store Cleanup..." "Yellow" "Info" $TargetComputer
try {
if (-not $CimSession -and $TargetComputer -eq $env:COMPUTERNAME) {
dism.exe /Online /Cleanup-Image /StartComponentCleanup /ResetBase | Out-Null
} else {
Invoke-CimMethod -CimSession $CimSession -ClassName Win32_Process -MethodName Create -Arguments @{
CommandLine = 'dism.exe /Online /Cleanup-Image /StartComponentCleanup'
} | Out-Null
}
Write-ColorOutput "DISM Component Store Cleanup initiated successfully." "Green" "Good" $TargetComputer
} catch {
Write-ColorOutput "Failed to execute DISM Cleanup: $_" "Red" "Critical" $TargetComputer
}
}
function Invoke-CleanMgrCleanup {
param ([string]$TargetComputer = $env:COMPUTERNAME, [Microsoft.Management.Infrastructure.CimSession]$CimSession = $null)
Write-ColorOutput "`nRunning Disk Cleanup (cleanmgr)..." "Yellow" "Info" $TargetComputer
try {
$drive = $env:SystemDrive -replace ':', ''
$regPath = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches\$drive"
if (-not $CimSession -and $TargetComputer -eq $env:COMPUTERNAME) {
$cleanupItems = @(
"Active Setup Temp Folder",
"BranchCache",
"Downloaded Program Files",
"GameNewsFiles",
"Internet Cache Files",
"Memory Dump Files",
"Old ChkDsk Files",
"Previous Installations",
"Recycle Bin",
"Setup Log Files",
"System error memory dump files",
"System error minidump files",
"Temporary Files",
"Temporary Setup Files",
"Temporary Sync Files",
"Windows Error Reporting Archive Files",
"Windows Error Reporting Queue Files",
"Windows Error Reporting System Archive Files",
"Windows Error Reporting System Queue Files",
"Windows Update Cleanup"
)
foreach ($item in $cleanupItems) {
$itemPath = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches\$item"
if (Test-Path $itemPath) {
New-ItemProperty -Path $itemPath -Name "StateFlags0001" -Value 2 -PropertyType DWord -Force | Out-Null
}
}
Start-Process -FilePath "cleanmgr.exe" -ArgumentList "/sagerun:1" -Wait -WindowStyle Normal
} else {
$scriptBlock = @"
`$drive = `$env:SystemDrive -replace ':', ''
`$cleanupItems = @(
"Active Setup Temp Folder",
"BranchCache",
"Downloaded Program Files",
"GameNewsFiles",
"Internet Cache Files",
"Memory Dump Files",
"Old ChkDsk Files",
"Previous Installations",
"Recycle Bin",
"Setup Log Files",
"System error memory dump files",
"System error minidump files",
"Temporary Files",
"Temporary Setup Files",
"Temporary Sync Files",
"Windows Error Reporting Archive Files",
"Windows Error Reporting Queue Files",
"Windows Error Reporting System Archive Files",
"Windows Error Reporting System Queue Files",
"Windows Update Cleanup"
)
foreach (`$item in `$cleanupItems) {
`$itemPath = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches\$item"
if (Test-Path `$itemPath) {
New-ItemProperty -Path `$itemPath -Name "StateFlags0001" -Value 2 -PropertyType DWord -Force | Out-Null
}
}
Start-Process -FilePath "cleanmgr.exe" -ArgumentList "/sagerun:1" -Wait -WindowStyle Normal
"@
Invoke-CimMethod -CimSession $CimSession -ClassName Win32_Process -MethodName Create -Arguments @{
CommandLine = "powershell.exe -Command `$scriptBlock"
} | Out-Null
}
Write-ColorOutput "Disk Cleanup completed." "Green" "Good" $TargetComputer
} catch {
Write-ColorOutput "Failed to execute Disk Cleanup: $_" "Red" "Critical" $TargetComputer
}
}
function Get-DiskSpaceInfo {
param ([string]$TargetComputer = $env:COMPUTERNAME, [Microsoft.Management.Infrastructure.CimSession]$CimSession = $null)
if (-not $CimSession -and $TargetComputer -eq $env:COMPUTERNAME) {
$disks = Get-PSDrive -PSProvider FileSystem |
Select-Object Name,
@{Name="FreeSpace(GB)";Expression={[math]::Round($_.Free/1GB, 2)}},
@{Name="TotalSpace(GB)";Expression={[math]::Round(($_.Used/1GB + $_.Free/1GB), 2)}},
@{Name="PercentFree";Expression={[math]::Round(($_.Free/($_.Used + $_.Free))*100, 2)}}
} else {
$disks = Get-CimInstance -ClassName Win32_LogicalDisk -Filter "DriveType=3" -CimSession $CimSession |
Select-Object DeviceID,
@{Name="FreeSpace(GB)";Expression={[math]::Round($_.FreeSpace/1GB, 2)}},
@{Name="TotalSpace(GB)";Expression={[math]::Round(($_.FreeSpace/1GB + $_.Size/1GB), 2)}},
@{Name="PercentFree";Expression={[math]::Round(($_.FreeSpace/($_.FreeSpace + $_.Size))*100, 2)}}
}
return $disks
}
function Clear-WindowsUpdateFiles {
param ([string]$TargetComputer = $env:COMPUTERNAME, [Microsoft.Management.Infrastructure.CimSession]$CimSession = $null)
Write-ColorOutput "`nCleaning Windows Update Files..." "Yellow" "Info" $TargetComputer
try {
$beforeSpace = Get-DiskSpaceInfo -TargetComputer $TargetComputer -CimSession $CimSession
if (-not $CimSession -and $TargetComputer -eq $env:COMPUTERNAME) {
Stop-Service -Name "wuauserv", "bits" -Force -ErrorAction SilentlyContinue
$updatePaths = @(
"$env:SystemRoot\SoftwareDistribution\Download\*",
"$env:SystemRoot\SoftwareDistribution\DataStore\*",
"$env:SystemRoot\SoftwareDistribution\Backup\*"
)
foreach ($path in $updatePaths) {
Remove-Item -Path $path -Recurse -Force -ErrorAction SilentlyContinue
}
$oldUpdates = "$env:SystemRoot\WinSxS\Backup\*"
if (Test-Path $oldUpdates) {
Remove-Item -Path $oldUpdates -Recurse -Force -ErrorAction SilentlyContinue
}
Start-Service -Name "wuauserv", "bits" -ErrorAction SilentlyContinue
} else {
$systemRoot = (Get-CimInstance -ClassName Win32_OperatingSystem -CimSession $CimSession).SystemRoot
$scriptBlock = @"
Stop-Service -Name 'wuauserv', 'bits' -Force -ErrorAction SilentlyContinue
`$systemRoot = '$systemRoot'
`$updatePaths = @("`$systemRoot\SoftwareDistribution\Download\*", "`$systemRoot\SoftwareDistribution\DataStore\*", "`$systemRoot\SoftwareDistribution\Backup\*")
foreach (`$path in `$updatePaths) {
if (Test-Path `$path) {
Remove-Item -Path `$path -Recurse -Force -ErrorAction SilentlyContinue
}
}
`$oldUpdates = "`$systemRoot\WinSxS\Backup\*"
if (Test-Path `$oldUpdates) {
Remove-Item -Path `$oldUpdates -Recurse -Force -ErrorAction SilentlyContinue
}
Start-Service -Name 'wuauserv', 'bits' -ErrorAction SilentlyContinue
"@
Invoke-CimMethod -CimSession $CimSession -ClassName Win32_Process -MethodName Create -Arguments @{
CommandLine = "powershell.exe -Command `$scriptBlock"
} | Out-Null
}
$afterSpace = Get-DiskSpaceInfo -TargetComputer $TargetComputer -CimSession $CimSession
foreach ($disk in $beforeSpace) {
$before = $disk.'FreeSpace(GB)'
$after = ($afterSpace | Where-Object { $_.Name -eq $disk.Name }).'FreeSpace(GB)'
$freed = [math]::Round($after - $before, 2)
Write-ColorOutput "Drive $($disk.Name): Freed $freed GB (was $before GB, now $after GB free)" "Green" "Good" $TargetComputer
}
Write-ColorOutput "Windows Update files cleaned successfully." "Green" "Good" $TargetComputer
} catch {
Write-ColorOutput "Failed to clean Windows Update files: $_" "Red" "Critical" $TargetComputer
}
}
function Clear-BrowserCaches {
param ([string]$TargetComputer = $env:COMPUTERNAME, [Microsoft.Management.Infrastructure.CimSession]$CimSession = $null)
Write-ColorOutput "`nClearing Browser Caches..." "Yellow" "Info" $TargetComputer
try {
if (-not $CimSession -and $TargetComputer -eq $env:COMPUTERNAME) {
$userProfiles = Get-ChildItem -Path "C:\Users" -Directory -ErrorAction SilentlyContinue
foreach ($profile in $userProfiles) {
$username = $profile.Name
$chromeCache = "$($profile.FullName)\AppData\Local\Google\Chrome\User Data\Default\Cache\*"
$chromeCodeCache = "$($profile.FullName)\AppData\Local\Google\Chrome\User Data\Default\Code Cache\*"
$firefoxCache = "$($profile.FullName)\AppData\Local\Mozilla\Firefox\Profiles\*\cache*"
$edgeCache = "$($profile.FullName)\AppData\Local\Microsoft\Edge\User Data\Default\Cache\*"
foreach ($path in @($chromeCache, $chromeCodeCache, $firefoxCache, $edgeCache)) {
if (Test-Path $path) {
Remove-Item -Path $path -Recurse -Force -ErrorAction SilentlyContinue
}
}
Write-ColorOutput " Cleared browser caches for user: $username" "White" "Info" $TargetComputer
}
} else {
$systemRoot = (Get-CimInstance -ClassName Win32_OperatingSystem -CimSession $CimSession).SystemRoot
$scriptBlock = @"
`$systemRoot = '$systemRoot'
`$userProfiles = Get-ChildItem -Path 'C:\Users' -Directory -ErrorAction SilentlyContinue
foreach (`$profile in `$userProfiles) {
`$username = `$profile.Name
`$chromeCache = "`$(`$profile.FullName)\AppData\Local\Google\Chrome\User Data\Default\Cache\*"
`$chromeCodeCache = "`$(`$profile.FullName)\AppData\Local\Google\Chrome\User Data\Default\Code Cache\*"
`$firefoxCache = "`$(`$profile.FullName)\AppData\Local\Mozilla\Firefox\Profiles\*\cache*"
`$edgeCache = "`$(`$profile.FullName)\AppData\Local\Microsoft\Edge\User Data\Default\Cache\*"
foreach (`$path in @(`$chromeCache, `$chromeCodeCache, `$firefoxCache, `$edgeCache)) {
if (Test-Path `$path) {
Remove-Item -Path `$path -Recurse -Force -ErrorAction SilentlyContinue
}
}
Write-Host " Cleared browser caches for user: `$username" -ForegroundColor White
}
"@
Invoke-CimMethod -CimSession $CimSession -ClassName Win32_Process -MethodName Create -Arguments @{
CommandLine = "powershell.exe -Command `$scriptBlock"
} | Out-Null
}
Write-ColorOutput "Browser caches cleared successfully." "Green" "Good" $TargetComputer
} catch {
Write-ColorOutput "Failed to clear browser caches: $_" "Red" "Critical" $TargetComputer
}
}
function Run-AllRemediations {
param ([string]$TargetComputer = $env:COMPUTERNAME)
Write-ColorOutput "`n===== Running All Remediation Tasks =====" "Cyan" "Info" $TargetComputer
$cimSession = $null
if ($TargetComputer -ne $env:COMPUTERNAME) {
$cimSession = Get-CimSessionForComputer -TargetComputer $TargetComputer -Credential $Credential
}
try {
Clear-WindowsUpdateCache -TargetComputer $TargetComputer -CimSession $cimSession
Clear-WindowsUpdateFiles -TargetComputer $TargetComputer -CimSession $cimSession
Clear-TempFiles -TargetComputer $TargetComputer -CimSession $cimSession -MaxAgeDays $script:TempFileAgeDays
Clear-WerDumps -TargetComputer $TargetComputer -CimSession $cimSession
Reset-NetworkStack -TargetComputer $TargetComputer -CimSession $cimSession
Repair-StoppedAutomaticServices -TargetComputer $TargetComputer -CimSession $cimSession
Clear-RecycleBinFiles -TargetComputer $TargetComputer -CimSession $cimSession
Invoke-DismCleanup -TargetComputer $TargetComputer -CimSession $cimSession
Invoke-CleanMgrCleanup -TargetComputer $TargetComputer -CimSession $cimSession
Clear-BrowserCaches -TargetComputer $TargetComputer -CimSession $cimSession
Write-ColorOutput "`nRemediation Cycle Completed!" "Cyan" "Good" $TargetComputer
} finally {
if ($cimSession) { Remove-CimSession $cimSession }
}
}
# Execution Logic
if ($RunAllRemediations -or $Silent) {
if ($ComputerName) {
foreach ($computer in $ComputerName) {
Show-Banner -TargetComputer $computer
Run-AllRemediations -TargetComputer $computer
}
} else {
Show-Banner
Run-AllRemediations
}
exit
}
# Interactive Loop
Show-Banner
$exitRequested = $false
while (-not $exitRequested) {
Show-Menu
$choice = Read-Host "Enter your choice"
switch ($choice.ToUpper()) {
"1" { Clear-WindowsUpdateCache }
"2" { Clear-TempFiles }
"3" { Clear-WerDumps }
"4" { Reset-NetworkStack }
"5" { Repair-StoppedAutomaticServices }
"6" { Clear-RecycleBinFiles }
"7" { Invoke-DismCleanup }
"8" { Invoke-CleanMgrCleanup }
"9" { Clear-BrowserCaches }
"10" { Run-AllRemediations }
"Q" { Write-ColorOutput "Exiting script..." "Cyan"; $exitRequested = $true }
default { Write-ColorOutput "Invalid selection." "Red" "Critical" }
}
if (-not $exitRequested) {
Write-ColorOutput "`nPress any key to continue..." "Yellow"
$null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
Clear-Host
Show-Banner
}
}