Files
lxs/windows/tools/repair.ps1
T

151 lines
5.3 KiB
PowerShell

<#
LXS - System Repair (Windows)
Description: Integrity repair for the component store and system files
(SFC, DISM, chkdsk). Requires administrator rights.
Repo: https://git.hyko.cx/hykocx/lxs
#>
# Load LXS common library (colors, UI helpers, spinner, loggers, guards).
# Prefers the sibling ..\lib\common.ps1 (repo checkout or installed layout) and
# only hits the network when this script is run standalone.
$LxsRawBase = if ($env:LXS_RAW_BASE) { $env:LXS_RAW_BASE } else { 'https://git.hyko.cx/hykocx/lxs/raw/branch/main' }
if (-not $env:LXS_RAW_PLATFORM_BASE) { $env:LXS_RAW_PLATFORM_BASE = "$LxsRawBase/windows" }
$LxsLibPath = if ($PSScriptRoot) { Join-Path $PSScriptRoot '..\lib\common.ps1' } else { $null }
if ($LxsLibPath -and (Test-Path $LxsLibPath)) {
. $LxsLibPath
} else {
try {
$LxsLibSource = Invoke-RestMethod -Uri "$env:LXS_RAW_PLATFORM_BASE/lib/common.ps1" -UseBasicParsing -ErrorAction Stop
} catch {
Write-Error 'Failed to fetch lib/common.ps1'
exit 1
}
. ([scriptblock]::Create($LxsLibSource))
}
$env:LXS_LOG_FILE = Join-Path (Get-LxsTempDir) 'lxs_repair.log'
if (-not (Assert-LxsWindows)) { exit 1 }
Assert-LxsAdmin -ScriptPath $PSCommandPath -Arguments $args
# These commands stream long-running progress; running them through the
# spinner would hide it, so they write straight to the console.
function Invoke-LxsRepairCommand {
param(
[Parameter(Mandatory = $true)][string]$Title,
[Parameter(Mandatory = $true)][string]$Exe,
[Parameter(Mandatory = $true)][string[]]$CmdArgs,
[string]$Note = ''
)
Clear-Host
Show-LxsBoxTop -Title $Title
Write-Host ''
if ($Note) {
Write-Host "$($script:Gray)$Note$($script:NC)"
Write-Host ''
}
Write-LxsInfo "$Exe $($CmdArgs -join ' ')"
Show-LxsSeparator
Write-Host ''
& $Exe @CmdArgs
$code = $LASTEXITCODE
Write-Host ''
Show-LxsSeparator
if ($code -eq 0) {
Write-LxsOk "$Title completed"
} else {
Write-LxsWarn "$Title exited with code $code"
}
return $code
}
function Invoke-LxsSfc {
Invoke-LxsRepairCommand -Title 'SFC SCANNOW' -Exe 'sfc.exe' -CmdArgs @('/scannow') `
-Note 'Verifies every protected system file and repairs corrupted ones from the component store. Takes 5-15 minutes.' | Out-Null
}
function Invoke-LxsDism {
Clear-Host
Show-LxsBoxTop -Title 'DISM RESTOREHEALTH'
Write-Host ''
Write-Host "$($script:Gray)Repairs the component store itself. Run this before SFC when SFC$($script:NC)"
Write-Host "$($script:Gray)reports that it cannot fix files. Needs internet access for the$($script:NC)"
Write-Host "$($script:Gray)replacement payloads. Takes 10-30 minutes.$($script:NC)"
Write-Host ''
Show-LxsSeparator
Write-Host ''
Write-LxsInfo 'Step 1/3 - CheckHealth'
& dism.exe /Online /Cleanup-Image /CheckHealth
Write-Host ''
Write-LxsInfo 'Step 2/3 - ScanHealth (slow)'
& dism.exe /Online /Cleanup-Image /ScanHealth
Write-Host ''
Write-LxsInfo 'Step 3/3 - RestoreHealth'
& dism.exe /Online /Cleanup-Image /RestoreHealth
$code = $LASTEXITCODE
Write-Host ''
Show-LxsSeparator
if ($code -eq 0) { Write-LxsOk 'DISM completed' } else { Write-LxsWarn "DISM exited with code $code" }
}
function Invoke-LxsChkdsk {
Invoke-LxsRepairCommand -Title 'CHKDSK SCAN' -Exe 'chkdsk.exe' -CmdArgs @($env:SystemDrive, '/scan') `
-Note 'Online, read-only scan of the system volume. It reports problems without taking the volume offline; a full /f repair needs a reboot.' | Out-Null
}
function Invoke-LxsFullRepair {
Clear-Host
Show-LxsBoxTop -Title 'FULL REPAIR PASS'
Write-Host ''
Write-Host 'Runs, in the recommended order:'
Write-Host ' 1. DISM /RestoreHealth (repair the component store)'
Write-Host ' 2. SFC /scannow (repair system files from that store)'
Write-Host ' 3. chkdsk /scan (check the file system)'
Write-Host ''
Write-Host "$($script:Gray)Budget 30-60 minutes. Nothing here is destructive.$($script:NC)"
Write-Host ''
if (-not (Confirm-LxsAction -Question 'Start the full repair pass?' -DefaultYes)) {
Write-LxsInfo 'Cancelled.'
return
}
Invoke-LxsDism
Read-LxsEnter
Invoke-LxsSfc
Read-LxsEnter
Invoke-LxsChkdsk
}
function Show-LxsRepairMenu {
while ($true) {
Clear-Host
Show-LxsBoxTop -Title 'SYSTEM REPAIR' -Right 'ADMIN'
Write-Host ''
Show-LxsMenuItem '1' 'SFC /scannow' 'repair system files'
Show-LxsMenuItem '2' 'DISM /RestoreHealth' 'repair component store'
Show-LxsMenuItem '3' 'chkdsk /scan' 'check the file system'
Show-LxsMenuItem '4' 'Full repair pass' 'DISM, then SFC, then chkdsk'
Show-LxsMenuItem '0' 'Back' '' -Exit
Write-Host ''
Show-LxsBoxBottom
Write-Host ''
$choice = Read-LxsChoice
Write-Host ''
switch ($choice) {
'1' { Invoke-LxsSfc; Read-LxsEnter }
'2' { Invoke-LxsDism; Read-LxsEnter }
'3' { Invoke-LxsChkdsk; Read-LxsEnter }
'4' { Invoke-LxsFullRepair; Read-LxsEnter }
'0' { return }
default { Write-LxsErr 'Invalid protocol. Select 0-4.'; Start-Sleep -Seconds 1 }
}
}
}
Show-LxsRepairMenu
exit 75