Files
Powershell/PCRemediation/Invoke-PCRemediation.ps1
T
Kevin Simmons 731227dabe Add Invoke-CleanMgrCleanup function
- Runs cleanmgr with all 20 standard cleanup items enabled
- Uses StateFlags0001 registry values for persistent configuration
- Supports both local and remote CIM sessions
- Updated menu to include option 8 for Disk Cleanup
2026-10-04 15:13:15 -05:00

579 lines
24 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, and handle pending reboot flags.
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 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)]
[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 (3+ 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. 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 = 3)
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 {
$scriptBlock = @"
`$tempPaths = @("$env:SystemRoot\Temp", "$env:LOCALAPPDATA\Temp")
`$maxAge = (Get-Date).AddDays(-$MaxAgeDays)
foreach (`$path in `$tempPaths) {
if (Test-Path `$path) {
Get-ChildItem -Path `$path -Recurse -Force -ErrorAction SilentlyContinue |
Where-Object { `$_.LastWriteTime -lt `$maxAge } |
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 `$maxAge } |
Remove-Item -Recurse -Force -ErrorAction SilentlyContinue
}
}
"@
Invoke-CimMethod -CimSession $CimSession -ClassName Win32_Process -MethodName Create -Arguments @{
CommandLine = "powershell.exe -Command `$scriptBlock"
} | 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 {
Invoke-CimMethod -CimSession $CimSession -ClassName Win32_Process -MethodName Create -Arguments @{
CommandLine = 'cmd.exe /c del /f /s /q %ProgramData%\Microsoft\Windows\WER\*'
} | 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 {
Invoke-CimMethod -CimSession $CimSession -ClassName Win32_Process -MethodName Create -Arguments @{
CommandLine = 'cmd.exe /c ipconfig /flushdns'
} | 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 {
$scriptBlock = @"
`$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 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-TempFiles -TargetComputer $TargetComputer -CimSession $cimSession -MaxAgeDays 3
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
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" { 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
}
}