Skip to content

Commit

Permalink
Lots of changes
Browse files Browse the repository at this point in the history
  • Loading branch information
Carterpersall committed Jan 26, 2024
1 parent df68102 commit a79b6f4
Showing 1 changed file with 137 additions and 23 deletions.
160 changes: 137 additions & 23 deletions functions/public/Invoke-WPFFixesUpdate.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,18 @@ function Invoke-WPFFixesUpdate {
.DESCRIPTION
1. (Aggressive Only) Scans the system for corruption using chkdsk, SFC, and DISM
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
3. Remove the QMGR Data file, which stores BITS jobs
4. (Aggressive Only) Renames the DataStore and CatRoot2 folders
Expand All @@ -23,7 +35,7 @@ function Invoke-WPFFixesUpdate {
13. Forces Windows Update to check for updates
.PARAMETER Aggressive
If specified, the script will take additional steps to repair Windows Update that are more dangerous or generally unnecessary
If specified, the script will take additional steps to repair Windows Update that are more dangerous, take a significant amount of time, or are generally unnecessary
#>

Expand All @@ -37,26 +49,114 @@ function Invoke-WPFFixesUpdate {
# Scan system for corruption
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
Start-Process -NoNewWindow -FilePath "chkdsk.exe" -ArgumentList "/scan", "/perf"
Write-Progress -Id 1 -ParentId 0 -Activity "Scanning for corruption" -Status "Running SFC..." -PercentComplete 25
Start-Process -NoNewWindow -FilePath "sfc.exe" -ArgumentList "/scannow"
Write-Progress -Id 1 -ParentId 0 -Activity "Scanning for corruption" -Status "Running DISM..." -PercentComplete 50
Start-Process -NoNewWindow -FilePath "dism.exe" -ArgumentList "/online", "/cleanup-image", "/restorehealth"
Write-Progress -Id 1 -ParentId 0 -Activity "Scanning for corruption" -Status "Running SFC again..." -PercentComplete 75
Start-Process -NoNewWindow -FilePath "sfc.exe" -ArgumentList "/scannow"
# 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
}


Write-Progress -Id 0 -Activity "Repairing Windows Update" -Status "Stopping Windows Update Services..." -PercentComplete 10
# Stop the Windows Update Services
Write-Progress -Id 2 -ParentId 0 -Activity "Stopping Services" -Status "Stopping BITS..." -PercentComplete 0
Stop-Service -Name BITS
Stop-Service -Name BITS -Force
Write-Progress -Id 2 -ParentId 0 -Activity "Stopping Services" -Status "Stopping wuauserv..." -PercentComplete 20
Stop-Service -Name wuauserv
Stop-Service -Name wuauserv -Force
Write-Progress -Id 2 -ParentId 0 -Activity "Stopping Services" -Status "Stopping appidsvc..." -PercentComplete 40
Stop-Service -Name appidsvc
Stop-Service -Name appidsvc -Force
Write-Progress -Id 2 -ParentId 0 -Activity "Stopping Services" -Status "Stopping cryptsvc..." -PercentComplete 60
Stop-Service -Name cryptsvc
Stop-Service -Name cryptsvc -Force
Write-Progress -Id 2 -ParentId 0 -Activity "Stopping Services" -Status "Completed" -PercentComplete 100


Expand Down Expand Up @@ -96,6 +196,7 @@ function Invoke-WPFFixesUpdate {

# Reregister the BITS and Windows Update DLLs
Write-Progress -Id 0 -Activity "Repairing Windows Update" -Status "Reregistering DLLs..." -PercentComplete 40
$oldLocation = Get-Location
Set-Location $env:systemroot\system32
$i = 0
$DLLs = @(
Expand All @@ -112,26 +213,27 @@ function Invoke-WPFFixesUpdate {
$i++
Start-Process -NoNewWindow -FilePath "regsvr32.exe" -ArgumentList "/s", $dll
}
Set-Location $oldLocation
Write-Progress -Id 5 -ParentId 0 -Activity "Reregistering DLLs" -Status "Completed" -PercentComplete 100


# Remove the WSUS client settings
if (Test-Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate") {
Write-Progress -Id 0 -Activity "Repairing Windows Update" -Status "Removing WSUS client settings..." -PercentComplete 60
Write-Progress -Id 6 -ParentId 0 -Activity "Removing WSUS client settings" -PercentComplete 0
Start-Process -NoNewWindow -FilePath "REG" -ArgumentList "DELETE", "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate", "/v", "AccountDomainSid", "/f"
Start-Process -NoNewWindow -FilePath "REG" -ArgumentList "DELETE", "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate", "/v", "PingID", "/f"
Start-Process -NoNewWindow -FilePath "REG" -ArgumentList "DELETE", "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate", "/v", "SusClientId", "/f"
Start-Process -NoNewWindow -FilePath "REG" -ArgumentList "DELETE", "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate", "/v", "AccountDomainSid", "/f" -RedirectStandardError $true
Start-Process -NoNewWindow -FilePath "REG" -ArgumentList "DELETE", "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate", "/v", "PingID", "/f" -RedirectStandardError $true
Start-Process -NoNewWindow -FilePath "REG" -ArgumentList "DELETE", "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate", "/v", "SusClientId", "/f" -RedirectStandardError $true
Write-Progress -Id 6 -ParentId 0 -Activity "Removing WSUS client settings" -Status "Completed" -PercentComplete 100
}


# Reset WinSock
Write-Progress -Id 0 -Activity "Repairing Windows Update" -Status "Resetting WinSock..." -PercentComplete 65
Write-Progress -Id 7 -ParentId 0 -Activity "Resetting WinSock" -Status "Resetting WinSock..." -PercentComplete 0
Start-Process -NoNewWindow -FilePath "netsh" -ArgumentList "winsock", "reset"
Start-Process -NoNewWindow -FilePath "netsh" -ArgumentList "winhttp", "reset", "proxy"
Start-Process -NoNewWindow -FilePath "netsh" -ArgumentList "int", "ip", "reset"
Start-Process -NoNewWindow -FilePath "netsh" -ArgumentList "winsock", "reset" -RedirectStandardOutput $true
Start-Process -NoNewWindow -FilePath "netsh" -ArgumentList "winhttp", "reset", "proxy" -RedirectStandardOutput $true
Start-Process -NoNewWindow -FilePath "netsh" -ArgumentList "int", "ip", "reset" -RedirectStandardOutput $true
Write-Progress -Id 7 -ParentId 0 -Activity "Resetting WinSock" -Status "Completed" -PercentComplete 100


Expand All @@ -148,10 +250,12 @@ function Invoke-WPFFixesUpdate {
Get-Service BITS | Set-Service -StartupType Manual -PassThru | Start-Service
Write-Progress -Id 9 -ParentId 0 -Activity "Starting Windows Update Services" -Status "Starting wuauserv..." -PercentComplete 25
Get-Service wuauserv | Set-Service -StartupType Manual -PassThru | Start-Service
Write-Progress -Id 9 -ParentId 0 -Activity "Starting Windows Update Services" -Status "Starting appidsvc..." -PercentComplete 50
Get-Service appidsvc | Set-Service -StartupType Manual -PassThru | Start-Service
Write-Progress -Id 9 -ParentId 0 -Activity "Starting Windows Update Services" -Status "Starting cryptsvc..." -PercentComplete 75
Get-Service cryptsvc | Set-Service -StartupType Automatic -PassThru | Start-Service
Write-Progress -Id 9 -ParentId 0 -Activity "Starting Windows Update Services" -Status "Starting AppIDSvc..." -PercentComplete 50
# The AppIDSvc service is protected, so the startup type has to be changed in the registry
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\AppIDSvc" -Name "Start" -Value "3" # Manual
Start-Service AppIDSvc
Write-Progress -Id 9 -ParentId 0 -Activity "Starting Windows Update Services" -Status "Starting CryptSvc..." -PercentComplete 75
Get-Service CryptSvc | Set-Service -StartupType Manual -PassThru | Start-Service
Write-Progress -Id 9 -ParentId 0 -Activity "Starting Windows Update Services" -Status "Completed" -PercentComplete 100


Expand All @@ -173,6 +277,16 @@ function Invoke-WPFFixesUpdate {
Write-Host "-- Reset All Windows Update Settings to Stock -"
Write-Host "==============================================="

# Remove the progress bar
# Remove the progress bars
Write-Progress -Id 0 -Activity "Repairing Windows Update" -Completed
Write-Progress -Id 1 -Activity "Scanning for corruption" -Completed
Write-Progress -Id 2 -Activity "Stopping Services" -Completed
Write-Progress -Id 3 -Activity "Renaming/Removing Files" -Completed
Write-Progress -Id 4 -Activity "Resetting the WU Service Security Descriptors" -Completed
Write-Progress -Id 5 -Activity "Reregistering DLLs" -Completed
Write-Progress -Id 6 -Activity "Removing WSUS client settings" -Completed
Write-Progress -Id 7 -Activity "Resetting WinSock" -Completed
Write-Progress -Id 8 -Activity "Deleting BITS jobs" -Completed
Write-Progress -Id 9 -Activity "Starting Windows Update Services" -Completed
Write-Progress -Id 10 -Activity "Forcing discovery" -Completed
}

0 comments on commit a79b6f4

Please sign in to comment.