mirror of
https://github.com/Raphire/Win11Debloat.git
synced 2026-08-23 08:02:07 +00:00
Refactor feature management scripts to improve error handling
This commit is contained in:
@@ -5,32 +5,42 @@
|
||||
function Invoke-ForceRemoveEdge {
|
||||
if ($script:Params.ContainsKey("WhatIf")) {
|
||||
Write-Host "[WhatIf] Forcefully uninstall Microsoft Edge" -ForegroundColor Cyan
|
||||
Write-Host ""
|
||||
return
|
||||
return $true
|
||||
}
|
||||
|
||||
Write-Host "> Forcefully uninstalling Microsoft Edge..."
|
||||
try {
|
||||
Write-Host "> Forcefully uninstalling Microsoft Edge..."
|
||||
|
||||
$regView = [Microsoft.Win32.RegistryView]::Registry32
|
||||
$hklm = [Microsoft.Win32.RegistryKey]::OpenBaseKey([Microsoft.Win32.RegistryHive]::LocalMachine, $regView)
|
||||
$hklm.CreateSubKey('SOFTWARE\Microsoft\EdgeUpdateDev').SetValue('AllowUninstall', '')
|
||||
$regView = [Microsoft.Win32.RegistryView]::Registry32
|
||||
$hklm = [Microsoft.Win32.RegistryKey]::OpenBaseKey([Microsoft.Win32.RegistryHive]::LocalMachine, $regView)
|
||||
$hklm.CreateSubKey('SOFTWARE\Microsoft\EdgeUpdateDev').SetValue('AllowUninstall', '')
|
||||
|
||||
# Create stub (This somehow allows uninstalling Edge)
|
||||
$edgeStub = "$env:SystemRoot\SystemApps\Microsoft.MicrosoftEdge_8wekyb3d8bbwe"
|
||||
New-Item $edgeStub -ItemType Directory | Out-Null
|
||||
New-Item "$edgeStub\MicrosoftEdge.exe" | Out-Null
|
||||
# Create stub (This somehow allows uninstalling Edge)
|
||||
$edgeStub = "$env:SystemRoot\SystemApps\Microsoft.MicrosoftEdge_8wekyb3d8bbwe"
|
||||
New-Item $edgeStub -ItemType Directory -Force -ErrorAction Stop | Out-Null
|
||||
New-Item "$edgeStub\MicrosoftEdge.exe" -ItemType File -Force -ErrorAction Stop | Out-Null
|
||||
|
||||
# Remove edge
|
||||
$uninstallRegKey = $hklm.OpenSubKey('SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Microsoft Edge')
|
||||
if ($null -ne $uninstallRegKey) {
|
||||
$uninstallRegKey = $hklm.OpenSubKey('SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Microsoft Edge')
|
||||
if ($null -eq $uninstallRegKey) {
|
||||
Write-Host "Unable to forcefully uninstall Microsoft Edge, uninstaller could not be found" -ForegroundColor Red
|
||||
return $false
|
||||
}
|
||||
|
||||
Write-Host "Running uninstaller..."
|
||||
$uninstallString = $uninstallRegKey.GetValue('UninstallString') + ' --force-uninstall'
|
||||
Invoke-NonBlocking -ScriptBlock {
|
||||
$exitCode = Invoke-NonBlocking -ScriptBlock {
|
||||
param($cmd)
|
||||
Start-Process cmd.exe "/c $cmd" -WindowStyle Hidden -Wait
|
||||
$process = Start-Process cmd.exe "/c $cmd" -WindowStyle Hidden -Wait -PassThru
|
||||
return $process.ExitCode
|
||||
} -ArgumentList $uninstallString
|
||||
if ($exitCode -ne 0) {
|
||||
Write-Warning "Microsoft Edge uninstaller failed with exit code $exitCode."
|
||||
return $false
|
||||
}
|
||||
|
||||
Write-Host "Removing leftover files..."
|
||||
$cleanupSucceeded = $true
|
||||
|
||||
$edgePaths = @(
|
||||
"$env:ProgramData\Microsoft\Windows\Start Menu\Programs\Microsoft Edge.lnk",
|
||||
@@ -44,22 +54,81 @@ function Invoke-ForceRemoveEdge {
|
||||
|
||||
foreach ($path in $edgePaths) {
|
||||
if (Test-Path -Path $path) {
|
||||
Remove-Item -Path $path -Force -Recurse -ErrorAction SilentlyContinue
|
||||
Write-Host " Removed $path" -ForegroundColor DarkGray
|
||||
try {
|
||||
Remove-Item -Path $path -Force -Recurse -ErrorAction Stop
|
||||
Write-Host " Removed $path" -ForegroundColor DarkGray
|
||||
}
|
||||
catch {
|
||||
Write-Warning "Failed to remove Edge leftover '$path': $($_.Exception.Message)"
|
||||
$cleanupSucceeded = $false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Write-Host "Cleaning up registry..."
|
||||
$registryCleanupSucceeded = $true
|
||||
|
||||
# Remove MS Edge from autostart
|
||||
reg delete "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run" /v "MicrosoftEdgeAutoLaunch_A9F6DCE4ABADF4F51CF45CD7129E3C6C" /f *>$null
|
||||
reg delete "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run" /v "Microsoft Edge Update" /f *>$null
|
||||
reg delete "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\StartupApproved\Run" /v "MicrosoftEdgeAutoLaunch_A9F6DCE4ABADF4F51CF45CD7129E3C6C" /f *>$null
|
||||
reg delete "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\StartupApproved\Run" /v "Microsoft Edge Update" /f *>$null
|
||||
# Remove MS Edge from autostart. Missing values are already-clean state,
|
||||
# while failures to inspect or remove an existing value are reported.
|
||||
$autostartValues = @(
|
||||
@{ Path = 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Run'; Name = 'MicrosoftEdgeAutoLaunch_A9F6DCE4ABADF4F51CF45CD7129E3C6C' },
|
||||
@{ Path = 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Run'; Name = 'Microsoft Edge Update' },
|
||||
@{ Path = 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\StartupApproved\Run'; Name = 'MicrosoftEdgeAutoLaunch_A9F6DCE4ABADF4F51CF45CD7129E3C6C' },
|
||||
@{ Path = 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\StartupApproved\Run'; Name = 'Microsoft Edge Update' }
|
||||
)
|
||||
foreach ($autostartValue in $autostartValues) {
|
||||
if (-not (Remove-EdgeAutostartValue -Path $autostartValue.Path -Name $autostartValue.Name)) {
|
||||
$registryCleanupSucceeded = $false
|
||||
}
|
||||
}
|
||||
|
||||
if (-not $cleanupSucceeded -or -not $registryCleanupSucceeded) {
|
||||
Write-Warning "Microsoft Edge was uninstalled, but some leftover files or autostart entries could not be removed."
|
||||
return $false
|
||||
}
|
||||
|
||||
Write-Host "Microsoft Edge was uninstalled"
|
||||
return $true
|
||||
}
|
||||
else {
|
||||
Write-Host "Unable to forcefully uninstall Microsoft Edge, uninstaller could not be found" -ForegroundColor Red
|
||||
catch {
|
||||
Write-Warning "Failed to forcefully uninstall Microsoft Edge: $($_.Exception.Message)"
|
||||
return $false
|
||||
}
|
||||
finally {
|
||||
if ($uninstallRegKey) { $uninstallRegKey.Dispose() }
|
||||
if ($hklm) { $hklm.Dispose() }
|
||||
}
|
||||
}
|
||||
|
||||
function Remove-EdgeAutostartValue {
|
||||
param(
|
||||
[Parameter(Mandatory)]
|
||||
[string]$Path,
|
||||
[Parameter(Mandatory)]
|
||||
[string]$Name
|
||||
)
|
||||
|
||||
try {
|
||||
$properties = Get-ItemProperty -Path $Path -ErrorAction Stop
|
||||
}
|
||||
catch [System.Management.Automation.ItemNotFoundException] {
|
||||
return $true
|
||||
}
|
||||
catch {
|
||||
Write-Warning "Failed to inspect Edge autostart entry '$Path\$Name': $($_.Exception.Message)"
|
||||
return $false
|
||||
}
|
||||
|
||||
if (-not $properties.PSObject.Properties[$Name]) {
|
||||
return $true
|
||||
}
|
||||
|
||||
try {
|
||||
Remove-ItemProperty -Path $Path -Name $Name -ErrorAction Stop
|
||||
return $true
|
||||
}
|
||||
catch {
|
||||
Write-Warning "Failed to remove Edge autostart entry '$Path\$Name': $($_.Exception.Message)"
|
||||
return $false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,10 +29,10 @@ function Remove-SelectedApps {
|
||||
Write-Host "[WhatIf] Remove App Package: $app" -ForegroundColor Cyan
|
||||
}
|
||||
|
||||
Write-Host ""
|
||||
return
|
||||
return $true
|
||||
}
|
||||
|
||||
$failuresBefore = $script:AppRemovalFailures
|
||||
$targetUser = Get-TargetUserForAppRemoval
|
||||
$appCount = @($appsList).Count
|
||||
$appIndex = 0
|
||||
@@ -42,7 +42,7 @@ function Remove-SelectedApps {
|
||||
$wingetRemovalFailures = @{}
|
||||
|
||||
Foreach ($app in $appsList) {
|
||||
if ($script:CancelRequested) { return }
|
||||
if ($script:CancelRequested) { return $false }
|
||||
|
||||
$appIndex++
|
||||
|
||||
@@ -53,9 +53,9 @@ function Remove-SelectedApps {
|
||||
Write-Host "Removing $app"
|
||||
|
||||
if ((Get-AppRemovalMethod $app) -eq 'WinGet') {
|
||||
if (-not (Remove-WinGetApp -app $app)) {
|
||||
$wingetRemovalFailures[$app] = $true
|
||||
}
|
||||
# WinGet exit codes are not a reliable removal outcome. The single
|
||||
# post-removal inventory check below determines final success.
|
||||
$null = Remove-WinGetApp -app $app
|
||||
$wingetRemovedApps += $app
|
||||
}
|
||||
else {
|
||||
@@ -66,17 +66,20 @@ function Remove-SelectedApps {
|
||||
}
|
||||
|
||||
if ($script:CancelRequested) {
|
||||
Write-Host ""
|
||||
return
|
||||
return $false
|
||||
}
|
||||
|
||||
# Check whether any winget-removed apps are still present, and report errors for each one.
|
||||
if ($wingetRemovedApps.Count -gt 0) {
|
||||
$postRemovalList = if ($script:WingetInstalled) { Get-WingetInstalledApps -TimeOut 10 -NonBlocking } else { $null }
|
||||
$edgeForceRemoveRequested = $false
|
||||
$edgeForceRemoveSucceeded = $false
|
||||
|
||||
if ($null -eq $postRemovalList) {
|
||||
$script:AppRemovalVerificationUnavailable = $true
|
||||
foreach ($app in $wingetRemovedApps) {
|
||||
$wingetRemovalFailures[$app] = $true
|
||||
}
|
||||
}
|
||||
else {
|
||||
foreach ($app in $wingetRemovedApps) {
|
||||
@@ -87,8 +90,11 @@ function Remove-SelectedApps {
|
||||
if ($edgeIds -contains $app) {
|
||||
Write-Host "Unable to uninstall Microsoft Edge via WinGet" -ForegroundColor Red
|
||||
if (-not $edgeForceRemoveRequested) {
|
||||
Request-EdgeForceRemove
|
||||
$edgeForceRemoveRequested = $true
|
||||
$edgeForceRemoveSucceeded = Request-EdgeForceRemove
|
||||
}
|
||||
if ($edgeForceRemoveSucceeded) {
|
||||
continue
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -101,7 +107,7 @@ function Remove-SelectedApps {
|
||||
|
||||
$script:AppRemovalFailures += $wingetRemovalFailures.Count
|
||||
|
||||
Write-Host ""
|
||||
return ($script:AppRemovalFailures -eq $failuresBefore)
|
||||
}
|
||||
|
||||
<#
|
||||
@@ -133,20 +139,30 @@ function Remove-WinGetApp {
|
||||
|
||||
$uninstallSucceeded = $true
|
||||
try {
|
||||
$uninstallSucceeded = Invoke-NonBlocking -ScriptBlock {
|
||||
$uninstallResult = Invoke-NonBlocking -ScriptBlock {
|
||||
param($appId)
|
||||
$null = & winget uninstall --accept-source-agreements --disable-interactivity --id $appId 2>&1
|
||||
return $true
|
||||
$output = @(& winget uninstall --accept-source-agreements --disable-interactivity --id $appId 2>&1)
|
||||
$exitCode = $LASTEXITCODE
|
||||
return [PSCustomObject]@{
|
||||
Success = ($exitCode -eq 0)
|
||||
ExitCode = $exitCode
|
||||
Output = $output
|
||||
}
|
||||
} -ArgumentList $app -TimeoutSeconds $TimeoutSeconds
|
||||
$uninstallSucceeded = [bool]$uninstallSucceeded
|
||||
$uninstallSucceeded = [bool]($uninstallResult -and $uninstallResult.Success)
|
||||
Write-WinGetUninstallOutput -Output $(if ($uninstallResult) { $uninstallResult.Output } else { $null })
|
||||
if (-not $uninstallSucceeded) {
|
||||
$exitCode = if ($uninstallResult) { $uninstallResult.ExitCode } else { 'unknown' }
|
||||
Write-Verbose "WinGet uninstall for $app returned exit code $exitCode. The post-removal inventory check will determine whether the app is still installed."
|
||||
}
|
||||
}
|
||||
catch {
|
||||
$uninstallSucceeded = $false
|
||||
if ($_.Exception.Message -like 'Operation timed out after *') {
|
||||
Write-Error "WinGet uninstall for $app did not complete within $TimeoutSeconds seconds: $_"
|
||||
Write-Verbose "WinGet uninstall for $app did not complete within $TimeoutSeconds seconds: $_"
|
||||
}
|
||||
else {
|
||||
Write-Error "WinGet uninstall for $app failed: $_"
|
||||
Write-Verbose "WinGet uninstall for $app failed: $_"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -163,6 +179,21 @@ function Remove-WinGetApp {
|
||||
return ($uninstallSucceeded -and $scheduleSucceeded)
|
||||
}
|
||||
|
||||
function Write-WinGetUninstallOutput {
|
||||
param(
|
||||
[object[]]$Output
|
||||
)
|
||||
|
||||
foreach ($line in @($Output)) {
|
||||
if ($null -eq $line) { continue }
|
||||
|
||||
$lineText = if ($line -is [System.Management.Automation.ErrorRecord]) { $line.Exception.Message } else { $line.ToString() }
|
||||
if ([string]::IsNullOrWhiteSpace($lineText)) { continue }
|
||||
|
||||
Write-Verbose $lineText
|
||||
}
|
||||
}
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Removes an app via Remove-AppxPackage / Remove-ProvisionedAppxPackage.
|
||||
@@ -283,13 +314,15 @@ function Request-EdgeForceRemove {
|
||||
$result = Show-MessageBox -Message 'Unable to uninstall Microsoft Edge via WinGet. Would you like to forcefully uninstall it? NOT RECOMMENDED!' -Title 'Force Uninstall Microsoft Edge?' -Button 'YesNo' -Icon 'Warning'
|
||||
if ($result -eq 'Yes') {
|
||||
Write-Host ""
|
||||
Invoke-ForceRemoveEdge
|
||||
return (Invoke-ForceRemoveEdge)
|
||||
}
|
||||
}
|
||||
elseif ($(Read-Host -Prompt "Would you like to forcefully uninstall Microsoft Edge? NOT RECOMMENDED! (y/n)") -eq 'y') {
|
||||
Write-Host ""
|
||||
Invoke-ForceRemoveEdge
|
||||
return (Invoke-ForceRemoveEdge)
|
||||
}
|
||||
|
||||
return $false
|
||||
}
|
||||
|
||||
<#
|
||||
|
||||
Reference in New Issue
Block a user