Skip to content

Instantly share code, notes, and snippets.

@michaelsanford
Last active February 11, 2026 15:22
Show Gist options
  • Select an option

  • Save michaelsanford/b74359375a617122bcf375efa20f41b6 to your computer and use it in GitHub Desktop.

Select an option

Save michaelsanford/b74359375a617122bcf375efa20f41b6 to your computer and use it in GitHub Desktop.
Windows 11 Maintenance (DISM, SFC, compact VM disks)
<#
.SYNOPSIS
Performs comprehensive Windows system maintenance tasks.
.DESCRIPTION
Runs a series of maintenance operations including Windows Defender scans, system integrity checks,
disk optimization, VHDX optimization, temporary file cleanup, and system error reporting.
All operations are logged to a timestamped file on the Desktop.
Captures performance metrics before and after maintenance.
.PARAMETER Force
Skips all confirmation prompts. Use for unattended/automated execution.
If a reboot is pending, automatically reboots without prompting.
.PARAMETER WhatIf
Shows what operations would be performed without actually executing them.
.PARAMETER Shutdown
Performs a full shutdown (/s /g) after maintenance completes. Prompts for confirmation unless -Force is used.
.EXAMPLE
.\Start-Maintenance.ps1
Runs maintenance interactively with confirmation prompts.
.EXAMPLE
.\Start-Maintenance.ps1 -Force
Runs maintenance without any prompts (unattended mode).
.EXAMPLE
.\Start-Maintenance.ps1 -WhatIf
Previews all maintenance operations without executing them.
.EXAMPLE
.\Start-Maintenance.ps1 -Force -Shutdown
Runs maintenance and performs a full shutdown without prompts.
.NOTES
Requires Administrator privileges.
Log files are saved to: $env:USERPROFILE\Desktop\WindowsMaintenance_<timestamp>.log
#>
#Requires -RunAsAdministrator
param(
[switch]$Force,
[switch]$WhatIf,
[switch]$Shutdown
)
$ErrorActionPreference = 'Stop'
$script:hasErrors = $false
$logFile = "$env:USERPROFILE\Desktop\WindowsMaintenance_$(Get-Date -Format 'yyyyMMdd_HHmmss').log"
if (-not $WhatIf) {
Start-Transcript -Path $logFile -Append
}
function Test-PendingReboot {
$rebootPending = $false
# Check Component Based Servicing
if (Get-ChildItem "HKLM:\Software\Microsoft\Windows\CurrentVersion\Component Based Servicing\RebootPending" -ErrorAction SilentlyContinue) {
$rebootPending = $true
}
# Check Windows Update
if (Get-Item "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired" -ErrorAction SilentlyContinue) {
$rebootPending = $true
}
# Check PendingFileRenameOperations
$pendingFileRename = Get-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager" -Name PendingFileRenameOperations -ErrorAction SilentlyContinue
if ($pendingFileRename) {
$rebootPending = $true
}
return $rebootPending
}
"Starting Windows maintenance routine..."
"Start time: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')"
""
# Capture baseline performance metrics
"Capturing baseline performance metrics..."
$bootTime = (Get-CimInstance -ClassName Win32_OperatingSystem).LastBootUpTime
$uptime = (Get-Date) - $bootTime
$memoryBefore = Get-CimInstance -ClassName Win32_OperatingSystem | Select-Object FreePhysicalMemory, TotalVisibleMemorySize
"System uptime: $($uptime.Days) days, $($uptime.Hours) hours, $($uptime.Minutes) minutes"
"Free memory: $([math]::Round($memoryBefore.FreePhysicalMemory / 1MB, 2)) GB of $([math]::Round($memoryBefore.TotalVisibleMemorySize / 1MB, 2)) GB"
""
# Check and shutdown WSL if enabled
Write-Progress -Activity "Windows Maintenance" -Status "Checking WSL status" -PercentComplete 5
$wslFeature = Get-WindowsOptionalFeature -Online -FeatureName Microsoft-Windows-Subsystem-Linux -ErrorAction SilentlyContinue
if ($wslFeature -and $wslFeature.State -eq 'Enabled') {
if ($Force -or $WhatIf -or $PSCmdlet.ShouldContinue("Shut down WSL to release VHDX locks for optimization?", "WSL Shutdown")) {
"Shutting down WSL..."
if (-not $WhatIf) {
wsl --shutdown
if ($LASTEXITCODE -ne 0) {
Write-Warning "WSL shutdown failed with exit code $LASTEXITCODE"
$script:hasErrors = $true
}
}
}
}
$drives = Get-Volume | Where-Object {
$_.DriveLetter -match '^[A-Z]$' -and $_.FileSystem -ne $null -and $_.DriveType -eq "Fixed"
}
# Windows Defender scan
Write-Progress -Activity "Windows Maintenance" -Status "Running Windows Defender scan" -PercentComplete 10
"Running Windows Defender quick scan..."
if (-not $WhatIf) {
try {
Start-MpScan -ScanType QuickScan
} catch {
Write-Warning "Defender scan failed: $_"
$script:hasErrors = $true
}
}
# DISM
Write-Progress -Activity "Windows Maintenance" -Status "Running DISM restore health (this may take 15-20 minutes)" -PercentComplete 20
"Running DISM restore health (this may take 15-20 minutes)..."
if (-not $WhatIf) {
$dismResult = DISM /Online /Cleanup-Image /RestoreHealth
if ($LASTEXITCODE -ne 0) {
Write-Warning "DISM failed with exit code $LASTEXITCODE"
$script:hasErrors = $true
}
}
# SFC
Write-Progress -Activity "Windows Maintenance" -Status "Running system file checker (this may take 10-15 minutes)" -PercentComplete 40
"Running system file checker (this may take 10-15 minutes)..."
if (-not $WhatIf) {
$sfcResult = sfc /scannow
if ($LASTEXITCODE -ne 0) {
Write-Warning "SFC failed with exit code $LASTEXITCODE"
$script:hasErrors = $true
}
}
# Chkdsk
$driveCount = $drives.Count
$driveIndex = 0
foreach ($drive in $drives) {
$letter = $drive.DriveLetter
$percent = 50 + (($driveIndex / $driveCount) * 10)
Write-Progress -Activity "Windows Maintenance" -Status "Running chkdsk on drive $letter" -PercentComplete $percent
"Running chkdsk on drive $letter..."
if (-not $WhatIf) {
chkdsk.exe /scan "${letter}:"
if ($LASTEXITCODE -ne 0) {
Write-Warning "Chkdsk on ${letter}: failed with exit code $LASTEXITCODE"
$script:hasErrors = $true
}
}
$driveIndex++
}
# Optimize VHDX files
Write-Progress -Activity "Windows Maintenance" -Status "Optimizing VHDX files" -PercentComplete 60
"Optimizing VHDX files..."
$vhdxPaths = @(
"$Env:LOCALAPPDATA",
"$Env:USERPROFILE\AppData\Local\Packages"
)
foreach ($path in $vhdxPaths) {
if (Test-Path $path) {
Get-ChildItem -Path $path -Recurse -Filter *.vhdx -ErrorAction SilentlyContinue | ForEach-Object {
"Optimizing VHD: $($_.FullName)"
if (-not $WhatIf) {
try {
Optimize-VHD -Path $_.FullName -Mode Full
} catch {
Write-Warning "Failed to optimize $($_.FullName): $_"
$script:hasErrors = $true
}
}
}
}
}
# Optimize volumes
$driveIndex = 0
foreach ($drive in $drives) {
$letter = $drive.DriveLetter
$percent = 70 + (($driveIndex / $driveCount) * 15)
Write-Progress -Activity "Windows Maintenance" -Status "Optimizing drive $letter" -PercentComplete $percent
"Optimizing drive $letter..."
if (-not $WhatIf) {
try {
Optimize-Volume -DriveLetter $letter -NormalPriority -Verbose
} catch {
Write-Warning "Failed to optimize drive ${letter}: $_"
$script:hasErrors = $true
}
}
$driveIndex++
}
# Clean temp files older than 7 days
Write-Progress -Activity "Windows Maintenance" -Status "Cleaning temporary files" -PercentComplete 85
"Cleaning temporary files older than 7 days..."
if (-not $WhatIf) {
$cutoffDate = (Get-Date).AddDays(-7)
Get-ChildItem "$env:TEMP" -Recurse -ErrorAction SilentlyContinue |
Where-Object { $_.LastWriteTime -lt $cutoffDate } |
Remove-Item -Force -Recurse -ErrorAction SilentlyContinue
}
# Disk space report
Write-Progress -Activity "Windows Maintenance" -Status "Generating disk space report" -PercentComplete 90
""
"Disk space report:"
foreach ($drive in $drives) {
$letter = $drive.DriveLetter
$freeGB = "{0:N1}" -f ($drive.SizeRemaining / 1GB)
$totalGB = "{0:N1}" -f ($drive.Size / 1GB)
"Drive ${letter}: $freeGB GB free of $totalGB GB"
}
# Review system errors
Write-Progress -Activity "Windows Maintenance" -Status "Reviewing system errors" -PercentComplete 95
""
"Reviewing recent system errors..."
try {
$errors = Get-WinEvent -LogName System -FilterXPath "*[System[(Level=1 or Level=2) and TimeCreated[timediff(@SystemTime) <= 86400000]]]" -ErrorAction SilentlyContinue
if ($errors.Count -gt 0) {
$grouped = $errors | Group-Object Id | Sort-Object Count -Descending | Select-Object -First 10
"Top 10 error types in the last 24 hours:"
$grouped | ForEach-Object {
" Event ID $($_.Name): $($_.Count) occurrence(s)"
" Sample: $($_.Group[0].Message.Split("`n")[0])"
}
} else {
"No critical or error-level events in the last 24 hours."
}
} catch {
Write-Warning "Failed to retrieve event log: $_"
$script:hasErrors = $true
}
# Update Oh My Posh
if (Get-AppxPackage -Name 'ohmyposh.cli' -ErrorAction SilentlyContinue) {
"Updating Oh My Posh..."
if (-not $WhatIf) {
winget upgrade JanDeDobbeleer.OhMyPosh --source winget
}
}
# if (Get-Module -ListAvailable -Name PSWindowsUpdate) {
# "Checking for Windows Updates..."
# Import-Module PSWindowsUpdate
# Get-WindowsUpdate -AcceptAll -Install -AutoReboot
# } else {
# "PSWindowsUpdate module not found. Skipping update check."
# }
Write-Progress -Activity "Windows Maintenance" -Status "Complete" -PercentComplete 100 -Completed
# Capture post-maintenance metrics
""
"Capturing post-maintenance performance metrics..."
$memoryAfter = Get-CimInstance -ClassName Win32_OperatingSystem | Select-Object FreePhysicalMemory
$memoryFreed = [math]::Round(($memoryAfter.FreePhysicalMemory - $memoryBefore.FreePhysicalMemory) / 1MB, 2)
"Free memory after: $([math]::Round($memoryAfter.FreePhysicalMemory / 1MB, 2)) GB (change: $memoryFreed GB)"
""
"End time: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')"
"Windows maintenance complete!"
# Check for pending reboot
$rebootPending = Test-PendingReboot
if ($rebootPending) {
""
Write-Warning "A system reboot is pending to complete maintenance operations."
if ($Force) {
"Initiating automatic reboot due to -Force flag..."
if (-not $WhatIf) {
Stop-Transcript
shutdown /r /t 30 /c "Maintenance complete - reboot required to finalize repairs"
exit 0
}
} else {
if ($PSCmdlet.ShouldContinue("A reboot is required to complete maintenance. Reboot now?", "Pending Reboot")) {
if (-not $WhatIf) {
Stop-Transcript
shutdown /r /t 30 /c "Maintenance complete - reboot required to finalize repairs"
exit 0
}
}
}
}
if (-not $WhatIf) {
Stop-Transcript
}
if ($Shutdown) {
if ($Force -or $WhatIf -or $PSCmdlet.ShouldContinue("Perform a full shutdown (clears hibernation file)?", "System Shutdown")) {
"Initiating full shutdown..."
if (-not $WhatIf) {
shutdown /s /g /t 10 /c "Maintenance complete - performing full shutdown"
}
}
}
# Exit with appropriate code
if ($script:hasErrors) {
exit 1
} else {
exit 0
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment