mirror of
https://github.com/Raphire/Win11Debloat.git
synced 2026-08-22 07:36:25 +00:00
fix: honor cancellation during changes (#700)
Co-authored-by: Jeffrey <9938813+Raphire@users.noreply.github.com>
This commit is contained in:
@@ -5,11 +5,10 @@
|
|||||||
.DESCRIPTION
|
.DESCRIPTION
|
||||||
Iterates over the provided list of app identifiers and removes each one.
|
Iterates over the provided list of app identifiers and removes each one.
|
||||||
The removal method (winget vs. Appx cmdlets) is determined per-app from
|
The removal method (winget vs. Appx cmdlets) is determined per-app from
|
||||||
Apps.json. Microsoft Edge is deferred to the end of the loop so that all
|
Apps.json. A scheduled task is only created when the User or Sysprep
|
||||||
winget attempts run before any force-remove prompt. A scheduled task is
|
parameter was passed. After winget removal, the system is checked to
|
||||||
only created when the User or Sysprep parameter was passed.
|
confirm whether the app is still installed before reporting an error.
|
||||||
After each winget removal, the system is checked to confirm whether the
|
Returns early if the CancelRequested flag is set.
|
||||||
app is still installed before reporting an error.
|
|
||||||
|
|
||||||
.PARAMETER appsList
|
.PARAMETER appsList
|
||||||
An array of app package identifiers to remove (e.g. 'Microsoft.BingNews').
|
An array of app package identifiers to remove (e.g. 'Microsoft.BingNews').
|
||||||
@@ -39,7 +38,6 @@ function RemoveApps {
|
|||||||
$appIndex = 0
|
$appIndex = 0
|
||||||
|
|
||||||
$edgeIds = @('Microsoft.Edge', 'XPFFTQ037JWMHS')
|
$edgeIds = @('Microsoft.Edge', 'XPFFTQ037JWMHS')
|
||||||
$edgeAppsInList = @()
|
|
||||||
$wingetRemovedApps = @()
|
$wingetRemovedApps = @()
|
||||||
|
|
||||||
Foreach ($app in $appsList) {
|
Foreach ($app in $appsList) {
|
||||||
@@ -51,12 +49,6 @@ function RemoveApps {
|
|||||||
& $script:ApplySubStepCallback "Removing apps ($appIndex/$appCount)" $appIndex $appCount
|
& $script:ApplySubStepCallback "Removing apps ($appIndex/$appCount)" $appIndex $appCount
|
||||||
}
|
}
|
||||||
|
|
||||||
# Microsoft Edge is handled after the loop to avoid duplicate scheduled tasks and allow fallback if winget fails
|
|
||||||
if ($edgeIds -contains $app) {
|
|
||||||
$edgeAppsInList += $app
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
Write-Host "Removing $app"
|
Write-Host "Removing $app"
|
||||||
|
|
||||||
if ((Get-AppRemovalMethod $app) -eq 'WinGet') {
|
if ((Get-AppRemovalMethod $app) -eq 'WinGet') {
|
||||||
@@ -68,32 +60,32 @@ function RemoveApps {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# Remove Microsoft Edge
|
if ($script:CancelRequested) {
|
||||||
if ($edgeAppsInList.Count -gt 0) {
|
Write-Host ""
|
||||||
Remove-EdgeApp -edgeAppsInList $edgeAppsInList
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
# Check whether any winget-removed apps are still present, and report errors for each one.
|
# Check whether any winget-removed apps are still present, and report errors for each one.
|
||||||
if ($wingetRemovedApps.Count -gt 0 -or $edgeAppsInList.Count -gt 0) {
|
if ($wingetRemovedApps.Count -gt 0) {
|
||||||
$postRemovalList = if ($script:WingetInstalled) { GetInstalledAppsViaWinget -TimeOut 10 -NonBlocking } else { $null }
|
$postRemovalList = if ($script:WingetInstalled) { GetInstalledAppsViaWinget -TimeOut 10 -NonBlocking } else { $null }
|
||||||
|
$edgeForceRemoveRequested = $false
|
||||||
|
|
||||||
foreach ($app in $wingetRemovedApps) {
|
foreach ($app in $wingetRemovedApps) {
|
||||||
if (Test-AppStillInstalled -appId $app -InstalledList $postRemovalList) {
|
if (-not (Test-AppStillInstalled -appId $app -InstalledList $postRemovalList)) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($edgeIds -contains $app) {
|
||||||
|
Write-Host "Unable to uninstall Microsoft Edge via WinGet" -ForegroundColor Red
|
||||||
|
if (-not $edgeForceRemoveRequested) {
|
||||||
|
Request-EdgeForceRemove
|
||||||
|
$edgeForceRemoveRequested = $true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
Write-Host "Unable to uninstall $app via WinGet" -ForegroundColor Red
|
Write-Host "Unable to uninstall $app via WinGet" -ForegroundColor Red
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# Verify Edge separately (triggers its own force-remove path if still installed)
|
|
||||||
$edgeStillInstalled = $false
|
|
||||||
foreach ($edgeApp in $edgeAppsInList) {
|
|
||||||
if (Test-AppStillInstalled -appId $edgeApp -InstalledList $postRemovalList) {
|
|
||||||
$edgeStillInstalled = $true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ($edgeStillInstalled) {
|
|
||||||
Write-Host "Unable to uninstall Microsoft Edge via WinGet" -ForegroundColor Red
|
|
||||||
Request-EdgeForceRemove
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Write-Host ""
|
Write-Host ""
|
||||||
@@ -101,15 +93,11 @@ function RemoveApps {
|
|||||||
|
|
||||||
<#
|
<#
|
||||||
.SYNOPSIS
|
.SYNOPSIS
|
||||||
Uninstalls a non-Edge app via WinGet and/or schedules its removal.
|
Uninstalls an app via WinGet and/or schedules its removal.
|
||||||
|
|
||||||
.DESCRIPTION
|
.DESCRIPTION
|
||||||
Runs winget uninstall for a single app. If the User or Sysprep
|
Runs winget uninstall for a single app. If the User or Sysprep
|
||||||
parameter was passed, also schedules removal for future logins.
|
parameter was passed, also schedules removal for future logins.
|
||||||
After uninstall, the system is checked to confirm whether the app
|
|
||||||
is still present — winget output is not trusted on its
|
|
||||||
own, as it sometimes reports failure after a successful removal.
|
|
||||||
Edge apps are handled separately after the main loop.
|
|
||||||
|
|
||||||
.PARAMETER app
|
.PARAMETER app
|
||||||
The WinGet package ID to uninstall (e.g. 'Microsoft.BingNews').
|
The WinGet package ID to uninstall (e.g. 'Microsoft.BingNews').
|
||||||
@@ -122,6 +110,11 @@ function Remove-WinGetApp {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Invoke-NonBlocking -ScriptBlock {
|
||||||
|
param($appId)
|
||||||
|
winget uninstall --accept-source-agreements --disable-interactivity --id $appId
|
||||||
|
} -ArgumentList $app
|
||||||
|
|
||||||
if ($script:Params.ContainsKey("User")) {
|
if ($script:Params.ContainsKey("User")) {
|
||||||
Write-Host "Adding scheduled task to uninstall $app for user $(GetUserName)..."
|
Write-Host "Adding scheduled task to uninstall $app for user $(GetUserName)..."
|
||||||
Set-RunOnceWingetTask -appId $app
|
Set-RunOnceWingetTask -appId $app
|
||||||
@@ -130,51 +123,6 @@ function Remove-WinGetApp {
|
|||||||
Write-Host "Adding scheduled task to uninstall $app for new users..."
|
Write-Host "Adding scheduled task to uninstall $app for new users..."
|
||||||
Set-RunOnceWingetTask -appId $app
|
Set-RunOnceWingetTask -appId $app
|
||||||
}
|
}
|
||||||
|
|
||||||
Invoke-NonBlocking -ScriptBlock {
|
|
||||||
param($appId)
|
|
||||||
winget uninstall --accept-source-agreements --disable-interactivity --id $appId
|
|
||||||
} -ArgumentList $app
|
|
||||||
}
|
|
||||||
|
|
||||||
<#
|
|
||||||
.SYNOPSIS
|
|
||||||
Removes Microsoft Edge via WinGet (both AppIds), with fallback to force-remove.
|
|
||||||
|
|
||||||
.DESCRIPTION
|
|
||||||
Edge has multiple package IDs. Runs winget uninstall for each one,
|
|
||||||
then creates a single scheduled task if the User or Sysprep parameter
|
|
||||||
was passed. After all attempts, the system is checked to confirm
|
|
||||||
whether Edge is still present. The force-remove prompt only
|
|
||||||
appears if Edge remains installed — winget false positives are ignored.
|
|
||||||
|
|
||||||
.PARAMETER edgeAppsInList
|
|
||||||
The Edge AppIds that appear in the removal list (one or both).
|
|
||||||
#>
|
|
||||||
function Remove-EdgeApp {
|
|
||||||
param([string[]]$edgeAppsInList)
|
|
||||||
|
|
||||||
if (-not $script:WingetInstalled) {
|
|
||||||
Write-Host "ERROR: WinGet is either not installed or is outdated, Microsoft Edge could not be removed" -ForegroundColor Red
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($script:Params.ContainsKey("User")) {
|
|
||||||
Write-Host "Adding scheduled task to uninstall Microsoft Edge for user $(GetUserName)..."
|
|
||||||
Set-RunOnceWingetTask -appId 'Microsoft.Edge'
|
|
||||||
}
|
|
||||||
elseif ($script:Params.ContainsKey("Sysprep")) {
|
|
||||||
Write-Host "Adding scheduled task to uninstall Microsoft Edge for new users..."
|
|
||||||
Set-RunOnceWingetTask -appId 'Microsoft.Edge'
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach ($edgeApp in $edgeAppsInList) {
|
|
||||||
Write-Host "Removing $edgeApp"
|
|
||||||
Invoke-NonBlocking -ScriptBlock {
|
|
||||||
param($appId)
|
|
||||||
winget uninstall --accept-source-agreements --disable-interactivity --id $appId
|
|
||||||
} -ArgumentList $edgeApp
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
<#
|
<#
|
||||||
@@ -389,4 +337,4 @@ function Set-RunOnceWingetTask {
|
|||||||
catch {
|
catch {
|
||||||
Write-Host "Failed to schedule uninstall task for $($appId): $_" -ForegroundColor Red
|
Write-Host "Failed to schedule uninstall task for $($appId): $_" -ForegroundColor Red
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,6 +40,8 @@ function Disable-TelemetryScheduledTasks {
|
|||||||
$tasks = Get-TelemetryScheduledTasks
|
$tasks = Get-TelemetryScheduledTasks
|
||||||
|
|
||||||
foreach ($task in $tasks) {
|
foreach ($task in $tasks) {
|
||||||
|
if ($script:CancelRequested) { return }
|
||||||
|
|
||||||
if ($script:Params.ContainsKey("WhatIf")) {
|
if ($script:Params.ContainsKey("WhatIf")) {
|
||||||
Write-Host "[WhatIf] Disable Scheduled Task: $($task.Path)$($task.Name)" -ForegroundColor Cyan
|
Write-Host "[WhatIf] Disable Scheduled Task: $($task.Path)$($task.Name)" -ForegroundColor Cyan
|
||||||
continue
|
continue
|
||||||
@@ -92,6 +94,8 @@ function Enable-TelemetryScheduledTasks {
|
|||||||
$tasks = Get-TelemetryScheduledTasks
|
$tasks = Get-TelemetryScheduledTasks
|
||||||
|
|
||||||
foreach ($task in $tasks) {
|
foreach ($task in $tasks) {
|
||||||
|
if ($script:CancelRequested) { return }
|
||||||
|
|
||||||
if ($script:Params.ContainsKey("WhatIf")) {
|
if ($script:Params.ContainsKey("WhatIf")) {
|
||||||
Write-Host "[WhatIf] Enable Scheduled Task: $($task.Path)$($task.Name)" -ForegroundColor Cyan
|
Write-Host "[WhatIf] Enable Scheduled Task: $($task.Path)$($task.Name)" -ForegroundColor Cyan
|
||||||
continue
|
continue
|
||||||
|
|||||||
@@ -563,6 +563,10 @@ if (($controlParamsCount -eq $script:Params.Keys.Count) -or ($script:Params.Keys
|
|||||||
# (This also handles restore point creation if requested)
|
# (This also handles restore point creation if requested)
|
||||||
Invoke-AllChanges
|
Invoke-AllChanges
|
||||||
|
|
||||||
|
if ($script:CancelRequested) {
|
||||||
|
Write-Warning "Script execution was cancelled by the user. Any remaining changes were not applied."
|
||||||
|
AwaitKeyToExit
|
||||||
|
}
|
||||||
|
|
||||||
# Restart Explorer process unless running in Sysprep or User context
|
# Restart Explorer process unless running in Sysprep or User context
|
||||||
if (-not ($script:Params.ContainsKey("Sysprep") -or $script:Params.ContainsKey("User"))) {
|
if (-not ($script:Params.ContainsKey("Sysprep") -or $script:Params.ContainsKey("User"))) {
|
||||||
|
|||||||
Reference in New Issue
Block a user