mirror of
https://github.com/ChrisTitusTech/winutil.git
synced 2025-05-10 00:02:09 +00:00
Refactor Invoke-WPFFixesUpdate and replace Invoke-WPFPanelDISM with Invoke-WPFSystemRepair. Streamline Windows Repair
This commit is contained in:
parent
698f1644c3
commit
642367509d
@ -34,7 +34,7 @@ function Invoke-WPFButton {
|
|||||||
"WPFRemoveUltPerf" {Invoke-WPFUltimatePerformance -State "Disable"}
|
"WPFRemoveUltPerf" {Invoke-WPFUltimatePerformance -State "Disable"}
|
||||||
"WPFundoall" {Invoke-WPFundoall}
|
"WPFundoall" {Invoke-WPFundoall}
|
||||||
"WPFFeatureInstall" {Invoke-WPFFeatureInstall}
|
"WPFFeatureInstall" {Invoke-WPFFeatureInstall}
|
||||||
"WPFPanelDISM" {Invoke-WPFPanelDISM}
|
"WPFPanelDISM" {Invoke-WPFSystemRepair}
|
||||||
"WPFPanelAutologin" {Invoke-WPFPanelAutologin}
|
"WPFPanelAutologin" {Invoke-WPFPanelAutologin}
|
||||||
"WPFPanelcontrol" {Invoke-WPFControlPanel -Panel $button}
|
"WPFPanelcontrol" {Invoke-WPFControlPanel -Panel $button}
|
||||||
"WPFPanelnetwork" {Invoke-WPFControlPanel -Panel $button}
|
"WPFPanelnetwork" {Invoke-WPFControlPanel -Panel $button}
|
||||||
|
@ -6,19 +6,7 @@ function Invoke-WPFFixesUpdate {
|
|||||||
Performs various tasks in an attempt to repair Windows Update
|
Performs various tasks in an attempt to repair Windows Update
|
||||||
|
|
||||||
.DESCRIPTION
|
.DESCRIPTION
|
||||||
1. (Aggressive Only) Scans the system for corruption using chkdsk, SFC, and DISM
|
1. (Aggressive Only) Scans the system for corruption using the Invoke-WPFSystemRepair function
|
||||||
Steps:
|
|
||||||
1. Runs chkdsk /scan /perf
|
|
||||||
/scan - Runs an online scan on the volume
|
|
||||||
/perf - Uses more system resources to complete a scan as fast as possible
|
|
||||||
2. Runs SFC /scannow
|
|
||||||
/scannow - Scans integrity of all protected system files and repairs files with problems when possible
|
|
||||||
3. Runs DISM /Online /Cleanup-Image /RestoreHealth
|
|
||||||
/Online - Targets the running operating system
|
|
||||||
/Cleanup-Image - Performs cleanup and recovery operations on the image
|
|
||||||
/RestoreHealth - Scans the image for component store corruption and attempts to repair the corruption using Windows Update
|
|
||||||
4. Runs SFC /scannow
|
|
||||||
Ran twice in case DISM repaired SFC
|
|
||||||
2. Stops Windows Update Services
|
2. Stops Windows Update Services
|
||||||
3. Remove the QMGR Data file, which stores BITS jobs
|
3. Remove the QMGR Data file, which stores BITS jobs
|
||||||
4. (Aggressive Only) Renames the DataStore and CatRoot2 folders
|
4. (Aggressive Only) Renames the DataStore and CatRoot2 folders
|
||||||
@ -46,104 +34,7 @@ function Invoke-WPFFixesUpdate {
|
|||||||
Start-Sleep -Milliseconds 200
|
Start-Sleep -Milliseconds 200
|
||||||
|
|
||||||
if ($Aggressive) {
|
if ($Aggressive) {
|
||||||
# Scan system for corruption
|
Invoke-WPFSystemRepair
|
||||||
Write-Progress -Id 0 -Activity "Repairing Windows Update" -Status "Scanning for corruption..." -PercentComplete 0
|
|
||||||
Write-Progress -Id 1 -ParentId 0 -Activity "Scanning for corruption" -Status "Running chkdsk..." -PercentComplete 0
|
|
||||||
# 2>&1 redirects stdout, alowing iteration over the output
|
|
||||||
chkdsk.exe /scan /perf 2>&1 | ForEach-Object {
|
|
||||||
# Write stdout to the Verbose stream
|
|
||||||
Write-Verbose $_
|
|
||||||
|
|
||||||
# Get the index of the total percentage
|
|
||||||
$index = $_.IndexOf("Total:")
|
|
||||||
if (
|
|
||||||
# If the percent is found
|
|
||||||
($percent = try {(
|
|
||||||
$_.Substring(
|
|
||||||
$index + 6,
|
|
||||||
$_.IndexOf("%", $index) - $index - 6
|
|
||||||
)
|
|
||||||
).Trim()} catch {0}) `
|
|
||||||
<# And the current percentage is greater than the previous one #>`
|
|
||||||
-and $percent -gt $oldpercent
|
|
||||||
) {
|
|
||||||
# Update the progress bar
|
|
||||||
$oldpercent = $percent
|
|
||||||
Write-Progress -Id 1 -ParentId 0 -Activity "Scanning for corruption" -Status "Running chkdsk... ($percent%)" -PercentComplete $percent
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Write-Progress -Id 1 -ParentId 0 -Activity "Scanning for corruption" -Status "Running SFC..." -PercentComplete 0
|
|
||||||
$oldpercent = 0
|
|
||||||
# SFC has a bug when redirected which causes it to output only when the stdout buffer is full, causing the progress bar to move in chunks
|
|
||||||
sfc /scannow 2>&1 | ForEach-Object {
|
|
||||||
# Write stdout to the Verbose stream
|
|
||||||
Write-Verbose $_
|
|
||||||
|
|
||||||
# Filter for lines that contain a percentage that is greater than the previous one
|
|
||||||
if (
|
|
||||||
(
|
|
||||||
# Use a different method to get the percentage that accounts for SFC's Unicode output
|
|
||||||
[int]$percent = try {(
|
|
||||||
(
|
|
||||||
$_.Substring(
|
|
||||||
$_.IndexOf("n") + 2,
|
|
||||||
$_.IndexOf("%") - $_.IndexOf("n") - 2
|
|
||||||
).ToCharArray() | Where-Object {$_}
|
|
||||||
) -join ''
|
|
||||||
).TrimStart()} catch {0}
|
|
||||||
) -and $percent -gt $oldpercent
|
|
||||||
) {
|
|
||||||
# Update the progress bar
|
|
||||||
$oldpercent = $percent
|
|
||||||
Write-Progress -Id 1 -ParentId 0 -Activity "Scanning for corruption" -Status "Running SFC... ($percent%)" -PercentComplete $percent
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Write-Progress -Id 1 -ParentId 0 -Activity "Scanning for corruption" -Status "Running DISM..." -PercentComplete 0
|
|
||||||
$oldpercent = 0
|
|
||||||
DISM /Online /Cleanup-Image /RestoreHealth | ForEach-Object {
|
|
||||||
# Write stdout to the Verbose stream
|
|
||||||
Write-Verbose $_
|
|
||||||
|
|
||||||
# Filter for lines that contain a percentage that is greater than the previous one
|
|
||||||
if (
|
|
||||||
($percent = try {
|
|
||||||
[int]($_ -replace "\[" -replace "=" -replace " " -replace "%" -replace "\]")
|
|
||||||
} catch {0}) `
|
|
||||||
-and $percent -gt $oldpercent
|
|
||||||
) {
|
|
||||||
# Update the progress bar
|
|
||||||
$oldpercent = $percent
|
|
||||||
Write-Progress -Id 1 -ParentId 0 -Activity "Scanning for corruption" -Status "Running DISM... ($percent%)" -PercentComplete $percent
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Write-Progress -Id 1 -ParentId 0 -Activity "Scanning for corruption" -Status "Running SFC again..." -PercentComplete 0
|
|
||||||
$oldpercent = 0
|
|
||||||
sfc /scannow 2>&1 | ForEach-Object {
|
|
||||||
# Write stdout to the Verbose stream
|
|
||||||
Write-Verbose $_
|
|
||||||
|
|
||||||
# Filter for lines that contain a percentage that is greater than the previous one
|
|
||||||
if (
|
|
||||||
(
|
|
||||||
[int]$percent = try {(
|
|
||||||
(
|
|
||||||
$_.Substring(
|
|
||||||
$_.IndexOf("n") + 2,
|
|
||||||
$_.IndexOf("%") - $_.IndexOf("n") - 2
|
|
||||||
).ToCharArray() | Where-Object {$_}
|
|
||||||
) -join ''
|
|
||||||
).TrimStart()} catch {0}
|
|
||||||
) -and $percent -gt $oldpercent
|
|
||||||
) {
|
|
||||||
# Update the progress bar
|
|
||||||
$oldpercent = $percent
|
|
||||||
Write-Progress -Id 1 -ParentId 0 -Activity "Scanning for corruption" -Status "Running SFC... ($percent%)" -PercentComplete $percent
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Write-Progress -Id 1 -ParentId 0 -Activity "Scanning for corruption" -Status "Completed" -PercentComplete 100
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,30 +0,0 @@
|
|||||||
function Invoke-WPFPanelDISM {
|
|
||||||
<#
|
|
||||||
|
|
||||||
.SYNOPSIS
|
|
||||||
Checks for system corruption using Chkdsk, SFC, and DISM
|
|
||||||
|
|
||||||
.DESCRIPTION
|
|
||||||
1. Chkdsk - Fixes disk and filesystem corruption
|
|
||||||
2. SFC Run 1 - Fixes system file corruption, and fixes DISM if it was corrupted
|
|
||||||
3. DISM - Fixes system image corruption, and fixes SFC's system image if it was corrupted
|
|
||||||
4. SFC Run 2 - Fixes system file corruption, this time with an almost guaranteed uncorrupted system image
|
|
||||||
|
|
||||||
.NOTES
|
|
||||||
Command Arguments:
|
|
||||||
1. Chkdsk
|
|
||||||
/Scan - Runs an online scan on the system drive, attempts to fix any corruption, and queues other corruption for fixing on reboot
|
|
||||||
2. SFC
|
|
||||||
/ScanNow - Performs a scan of the system files and fixes any corruption
|
|
||||||
3. DISM - Fixes system image corruption, and fixes SFC's system image if it was corrupted
|
|
||||||
/Online - Fixes the currently running system image
|
|
||||||
/Cleanup-Image - Performs cleanup operations on the image, could remove some unneeded temporary files
|
|
||||||
/Restorehealth - Performs a scan of the image and fixes any corruption
|
|
||||||
|
|
||||||
#>
|
|
||||||
Start-Process PowerShell -ArgumentList "Write-Host '(1/4) Chkdsk' -ForegroundColor Green; Chkdsk /scan;
|
|
||||||
Write-Host '`n(2/4) SFC - 1st scan' -ForegroundColor Green; sfc /scannow;
|
|
||||||
Write-Host '`n(3/4) DISM' -ForegroundColor Green; DISM /Online /Cleanup-Image /Restorehealth;
|
|
||||||
Write-Host '`n(4/4) SFC - 2nd scan' -ForegroundColor Green; sfc /scannow;
|
|
||||||
Read-Host '`nPress Enter to Continue'" -verb runas
|
|
||||||
}
|
|
165
functions/public/Invoke-WPFSystemRepair.ps1
Normal file
165
functions/public/Invoke-WPFSystemRepair.ps1
Normal file
@ -0,0 +1,165 @@
|
|||||||
|
function Invoke-WPFSystemRepair {
|
||||||
|
<#
|
||||||
|
|
||||||
|
.SYNOPSIS
|
||||||
|
Checks for system corruption using Chkdsk, SFC, and DISM
|
||||||
|
|
||||||
|
.DESCRIPTION
|
||||||
|
1. Chkdsk - Fixes disk and filesystem corruption
|
||||||
|
2. SFC Run 1 - Fixes system file corruption, and fixes DISM if it was corrupted
|
||||||
|
3. DISM - Fixes system image corruption, and fixes SFC's system image if it was corrupted
|
||||||
|
4. SFC Run 2 - Fixes system file corruption, this time with an almost guaranteed uncorrupted system image
|
||||||
|
#>
|
||||||
|
|
||||||
|
Write-Progress -Id 0 -Activity "Repairing Windows" -PercentComplete 0
|
||||||
|
# Wait for the first progress bar to show, otherwise the second one won't show
|
||||||
|
Start-Sleep -Milliseconds 200
|
||||||
|
|
||||||
|
function run_chkdsk {
|
||||||
|
<#
|
||||||
|
.SYNOPSIS
|
||||||
|
Runs chkdsk on the system drive
|
||||||
|
.DESCRIPTION
|
||||||
|
Chkdsk /Scan - Runs an online scan on the system drive, attempts to fix any corruption, and queues other corruption for fixing on reboot
|
||||||
|
.PARAMETER verbose
|
||||||
|
If specified, print output from chkdsk
|
||||||
|
.NOTES
|
||||||
|
VerbosePreference is defined locally, so it only affects this function. This is done by wrapping the code inside a script block and calling it with & { ... }
|
||||||
|
#>
|
||||||
|
param(
|
||||||
|
[switch]$verbose
|
||||||
|
)
|
||||||
|
& {
|
||||||
|
if ($verbose) {
|
||||||
|
$VerbosePreference = "Continue"
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$VerbosePreference = "SilentlyContinue"
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Progress -Id 1 -Activity "Scanning for corruption" -Status "Running chkdsk..." -PercentComplete 0
|
||||||
|
$oldpercent = 0
|
||||||
|
# 2>&1 redirects stdout, allowing iteration over the output
|
||||||
|
chkdsk.exe /scan /perf 2>&1 | ForEach-Object {
|
||||||
|
Write-Verbose $_
|
||||||
|
# Regex to match the total percentage regardless of windows locale (it's always the second percentage in the status output)
|
||||||
|
if ($_ -match "%.*?(\d+)%") {
|
||||||
|
[int]$percent = $matches[1]
|
||||||
|
if ($percent -gt $oldpercent) {
|
||||||
|
Write-Progress -Id 1 -ParentId 0 -Activity "Scanning for corruption" -Status "Running chkdsk... ($percent%)" -PercentComplete $percent
|
||||||
|
$oldpercent = $percent
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Write-Progress -Id 1 -Activity "Scanning for corruption" -Status "chkdsk Completed" -PercentComplete 100
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function run_sfc {
|
||||||
|
<#
|
||||||
|
.SYNOPSIS
|
||||||
|
Runs sfc on the system drive
|
||||||
|
.DESCRIPTION
|
||||||
|
SFC /ScanNow - Performs a scan of the system files and fixes any corruption
|
||||||
|
.PARAMETER verbose
|
||||||
|
If specified, print output from sfc
|
||||||
|
.NOTES
|
||||||
|
VerbosePreference and ErrorPreference is defined locally, so it only affects this function. This is done by wrapping the code inside a script block and calling it with & { ... }
|
||||||
|
#>
|
||||||
|
param(
|
||||||
|
[switch]$verbose
|
||||||
|
)
|
||||||
|
|
||||||
|
& {
|
||||||
|
if ($verbose) {
|
||||||
|
$VerbosePreference = "Continue"
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$VerbosePreference = "SilentlyContinue"
|
||||||
|
}
|
||||||
|
$ErrorActionPreference = "SilentlyContinue"
|
||||||
|
Write-Progress -Id 1 -ParentId 0 -Activity "Scanning for corruption" -Status "Running SFC..." -PercentComplete 0
|
||||||
|
$oldpercent = 0
|
||||||
|
# SFC has a bug when redirected which causes it to output only when the stdout buffer is full, causing the progress bar to move in chunks
|
||||||
|
sfc.exe /scannow 2>&1 | ForEach-Object {
|
||||||
|
Write-Verbose $_
|
||||||
|
if ($_ -ne "") {
|
||||||
|
# sfc.exe /scannow outputs unicode characters, so we directly remove null characters for optimization
|
||||||
|
$utf8line = $_ -replace "`0", ""
|
||||||
|
if ($utf8line -match "(\d+)\s%") {
|
||||||
|
# Write-Host "$($matches[0]) $($matches[1])"
|
||||||
|
[int]$percent = $matches[1]
|
||||||
|
if ($percent -gt $oldpercent) {
|
||||||
|
Write-Progress -Id 1 -ParentId 0 -Activity "Scanning for corruption" -Status "Running SFC... ($percent%)" -PercentComplete $percent
|
||||||
|
$oldpercent = $percent
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Write-Progress -Id 1 -ParentId 0 -Activity "Scanning for corruption" -Status "SFC Completed" -PercentComplete 100
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function run_dism {
|
||||||
|
<#
|
||||||
|
.SYNOPSIS
|
||||||
|
Runs DISM on the system drive
|
||||||
|
.DESCRIPTION
|
||||||
|
DISM - Fixes system image corruption, and fixes SFC's system image if it was corrupted
|
||||||
|
/Online - Fixes the currently running system image
|
||||||
|
/Cleanup-Image - Performs cleanup operations on the image, could remove some unneeded temporary files
|
||||||
|
/Restorehealth - Performs a scan of the image and fixes any corruption
|
||||||
|
|
||||||
|
.PARAMETER verbose
|
||||||
|
If specified, print output from DISM
|
||||||
|
.NOTES
|
||||||
|
VerbosePreference is defined locally, so it only affects this function. This is done by wrapping the code inside a script block and calling it with & { ... }
|
||||||
|
#>
|
||||||
|
param(
|
||||||
|
[switch]$verbose
|
||||||
|
)
|
||||||
|
& {
|
||||||
|
if ($verbose) {
|
||||||
|
$VerbosePreference = "Continue"
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$VerbosePreference = "SilentlyContinue"
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Progress -Id 1 -ParentId 0 -Activity "Scanning for corruption" -Status "Running DISM..." -PercentComplete 0
|
||||||
|
$oldpercent = 0
|
||||||
|
DISM /Online /Cleanup-Image /RestoreHealth | ForEach-Object {
|
||||||
|
Write-Verbose $_
|
||||||
|
|
||||||
|
# Filter for lines that contain a percentage that is greater than the previous one
|
||||||
|
if ($_ -match "(\d+)[.,]\d+%") {
|
||||||
|
[int]$percent = $matches[1]
|
||||||
|
if ($percent -gt $oldpercent) {
|
||||||
|
# Update the progress bar
|
||||||
|
Write-Progress -Id 1 -ParentId 0 -Activity "Scanning for corruption" -Status "Running DISM... ($percent%)" -PercentComplete $percent
|
||||||
|
$oldpercent = $percent
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Write-Progress -Id 1 -ParentId 0 -Activity "Scanning for corruption" -Status "DISM Completed" -PercentComplete 100
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Scan system for corruption
|
||||||
|
Write-Progress -Id 0 -Activity "Repairing Windows" -Status "Scanning for corruption... " -PercentComplete 0
|
||||||
|
# Step 1: Run chkdsk to fix disk and filesystem corruption before proceeding with system file repairs
|
||||||
|
run_chkdsk
|
||||||
|
Write-Progress -Id 0 -Activity "Repairing Windows" -Status "Scanning for corruption... (25%)" -PercentComplete 25
|
||||||
|
|
||||||
|
# Step 2: Run SFC to fix system file corruption and ensure DISM can operate correctly
|
||||||
|
run_sfc
|
||||||
|
Write-Progress -Id 0 -Activity "Repairing Windows" -Status "Scanning for corruption... (50%)" -PercentComplete 50
|
||||||
|
|
||||||
|
# Step 3: Run DISM to repair the system image, which SFC relies on for accurate repairs
|
||||||
|
run_dism
|
||||||
|
Write-Progress -Id 0 -Activity "Repairing Windows" -Status "Scanning for corruption... (75%)" -PercentComplete 75
|
||||||
|
|
||||||
|
# Step 4: Run SFC again to ensure system files are repaired using the now-fixed system image
|
||||||
|
run_sfc
|
||||||
|
Write-Progress -Id 0 -Activity "Repairing Windows" -Status "Scanning for corruption completed" -PercentComplete 100
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user