mirror of
https://github.com/Raphire/Win11Debloat.git
synced 2026-07-03 07:08:27 +00:00
feat(registry): add GPO override warning and WhatIf dry-run previews (#611)
Co-authored-by: Jeffrey <9938813+Raphire@users.noreply.github.com>
This commit is contained in:
@@ -25,6 +25,15 @@ function RemoveApps {
|
|||||||
$appslist
|
$appslist
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if ($script:Params.ContainsKey("WhatIf")) {
|
||||||
|
foreach ($app in $appslist) {
|
||||||
|
Write-Host "[WhatIf] Remove App Package: $app" -ForegroundColor Cyan
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Host ""
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
# Determine target from script-level params, defaulting to AllUsers
|
# Determine target from script-level params, defaulting to AllUsers
|
||||||
$targetUser = GetTargetUserForAppRemoval
|
$targetUser = GetTargetUserForAppRemoval
|
||||||
|
|
||||||
|
|||||||
@@ -77,7 +77,9 @@ function ExecuteParameter {
|
|||||||
'DisableWidgets' {
|
'DisableWidgets' {
|
||||||
Write-Host "> $($feature.ApplyText)..."
|
Write-Host "> $($feature.ApplyText)..."
|
||||||
# Stop widgets related processes before removing the app packages to prevent potential issues
|
# Stop widgets related processes before removing the app packages to prevent potential issues
|
||||||
Get-Process *Widget* -ErrorAction SilentlyContinue | Stop-Process
|
if (-not $script:Params.ContainsKey("WhatIf")) {
|
||||||
|
Get-Process *Widget* -ErrorAction SilentlyContinue | Stop-Process
|
||||||
|
}
|
||||||
|
|
||||||
RemoveApps @('Microsoft.StartExperiencesApp','MicrosoftWindows.Client.WebExperience','Microsoft.WidgetsPlatformRuntime')
|
RemoveApps @('Microsoft.StartExperiencesApp','MicrosoftWindows.Client.WebExperience','Microsoft.WidgetsPlatformRuntime')
|
||||||
}
|
}
|
||||||
@@ -185,18 +187,23 @@ function ExecuteAllChanges {
|
|||||||
& $script:ApplyProgressCallback $currentStep $totalSteps "Creating registry backup..."
|
& $script:ApplyProgressCallback $currentStep $totalSteps "Creating registry backup..."
|
||||||
}
|
}
|
||||||
|
|
||||||
Write-Host "> Creating registry backup..."
|
if ($script:Params.ContainsKey("WhatIf")) {
|
||||||
try {
|
Write-Host "[WhatIf] Create registry backup" -ForegroundColor Cyan
|
||||||
$undoSyntheticFeatures = @($script:UndoParams.Keys | ForEach-Object {
|
|
||||||
$f = if ($script:Features.ContainsKey($_)) { $script:Features[$_] } else { $null }
|
|
||||||
if ($f -and $f.RegistryUndoKey) {
|
|
||||||
[PSCustomObject]@{ FeatureId = $_; RegistryKey = (Resolve-UndoRegFilePath $f.RegistryUndoKey) }
|
|
||||||
}
|
|
||||||
} | Where-Object { $_ })
|
|
||||||
New-RegistrySettingsBackup -ActionableKeys $actionableKeys -ExtraFeatures $undoSyntheticFeatures | Out-Null
|
|
||||||
}
|
}
|
||||||
catch {
|
else {
|
||||||
throw "Registry backup failed before applying changes. $($_.Exception.Message)"
|
Write-Host "> Creating registry backup..."
|
||||||
|
try {
|
||||||
|
$undoSyntheticFeatures = @($script:UndoParams.Keys | ForEach-Object {
|
||||||
|
$f = if ($script:Features.ContainsKey($_)) { $script:Features[$_] } else { $null }
|
||||||
|
if ($f -and $f.RegistryUndoKey) {
|
||||||
|
[PSCustomObject]@{ FeatureId = $_; RegistryKey = (Resolve-UndoRegFilePath $f.RegistryUndoKey) }
|
||||||
|
}
|
||||||
|
} | Where-Object { $_ })
|
||||||
|
New-RegistrySettingsBackup -ActionableKeys $actionableKeys -ExtraFeatures $undoSyntheticFeatures | Out-Null
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
throw "Registry backup failed before applying changes. $($_.Exception.Message)"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -206,9 +213,15 @@ function ExecuteAllChanges {
|
|||||||
if ($script:ApplyProgressCallback) {
|
if ($script:ApplyProgressCallback) {
|
||||||
& $script:ApplyProgressCallback $currentStep $totalSteps "Creating system restore point, this may take a moment..."
|
& $script:ApplyProgressCallback $currentStep $totalSteps "Creating system restore point, this may take a moment..."
|
||||||
}
|
}
|
||||||
Write-Host "> Creating a system restore point..."
|
if ($script:Params.ContainsKey("WhatIf")) {
|
||||||
CreateSystemRestorePoint
|
Write-Host "[WhatIf] Create system restore point" -ForegroundColor Cyan
|
||||||
Write-Host ""
|
Write-Host ""
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Write-Host "> Creating a system restore point..."
|
||||||
|
CreateSystemRestorePoint
|
||||||
|
Write-Host ""
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# Execute all parameters
|
# Execute all parameters
|
||||||
|
|||||||
@@ -21,6 +21,12 @@ function ImportRegistryFile {
|
|||||||
$importScript = {
|
$importScript = {
|
||||||
param($targetRegFilePath, $hiveContext)
|
param($targetRegFilePath, $hiveContext)
|
||||||
|
|
||||||
|
if ($script:Params.ContainsKey("WhatIf")) {
|
||||||
|
Invoke-RegistryOperationsFromRegFile -RegFilePath $targetRegFilePath
|
||||||
|
Write-Host ""
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
# When the target user's hive is already loaded under their SID, the .reg file's
|
# When the target user's hive is already loaded under their SID, the .reg file's
|
||||||
# HKEY_USERS\Default paths won't match. Use the PowerShell registry writer instead,
|
# HKEY_USERS\Default paths won't match. Use the PowerShell registry writer instead,
|
||||||
# which remaps Default → SID via Split-RegistryPath.
|
# which remaps Default → SID via Split-RegistryPath.
|
||||||
|
|||||||
@@ -26,6 +26,11 @@ function ReplaceStartMenuForAllUsers {
|
|||||||
# Also replace the start menu file for the default user profile
|
# Also replace the start menu file for the default user profile
|
||||||
$defaultStartMenuPath = GetUserDirectory -userName "Default" -fileName "AppData\Local\Packages\Microsoft.Windows.StartMenuExperienceHost_cw5n1h2txyewy\LocalState" -exitIfPathNotFound $false
|
$defaultStartMenuPath = GetUserDirectory -userName "Default" -fileName "AppData\Local\Packages\Microsoft.Windows.StartMenuExperienceHost_cw5n1h2txyewy\LocalState" -exitIfPathNotFound $false
|
||||||
|
|
||||||
|
if ($script:Params.ContainsKey("WhatIf")) {
|
||||||
|
Write-Host "[WhatIf] Replace Start Menu for Default user profile with template $startMenuTemplate" -ForegroundColor Cyan
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
# Create folder if it doesn't exist
|
# Create folder if it doesn't exist
|
||||||
if (-not (Test-Path $defaultStartMenuPath)) {
|
if (-not (Test-Path $defaultStartMenuPath)) {
|
||||||
new-item $defaultStartMenuPath -ItemType Directory -Force | Out-Null
|
new-item $defaultStartMenuPath -ItemType Directory -Force | Out-Null
|
||||||
@@ -61,6 +66,11 @@ function ReplaceStartMenu {
|
|||||||
|
|
||||||
$userName = GetStartMenuUserNameFromPath -StartMenuBinFile $startMenuBinFile
|
$userName = GetStartMenuUserNameFromPath -StartMenuBinFile $startMenuBinFile
|
||||||
|
|
||||||
|
if ($script:Params.ContainsKey("WhatIf")) {
|
||||||
|
Write-Host "[WhatIf] Replace Start Menu for user $userName with template $startMenuTemplate" -ForegroundColor Cyan
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
$backupBinFile = $startMenuBinFile + ".bak"
|
$backupBinFile = $startMenuBinFile + ".bak"
|
||||||
|
|
||||||
if (Test-Path $startMenuBinFile) {
|
if (Test-Path $startMenuBinFile) {
|
||||||
@@ -121,6 +131,15 @@ function RestoreStartMenuFromBackup {
|
|||||||
}
|
}
|
||||||
$currentBinBackup = $StartMenuBinFile + '.restore.bak'
|
$currentBinBackup = $StartMenuBinFile + '.restore.bak'
|
||||||
|
|
||||||
|
if ($script:Params.ContainsKey("WhatIf")) {
|
||||||
|
Write-Host "[WhatIf] Restore start menu for user $userName from backup $backupBinFile" -ForegroundColor Cyan
|
||||||
|
return [PSCustomObject]@{
|
||||||
|
UserName = $userName
|
||||||
|
Result = $true
|
||||||
|
Message = "[WhatIf] Restored start menu for user $userName."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (-not (Test-Path -LiteralPath $backupBinFile)) {
|
if (-not (Test-Path -LiteralPath $backupBinFile)) {
|
||||||
return [PSCustomObject]@{
|
return [PSCustomObject]@{
|
||||||
UserName = $userName
|
UserName = $userName
|
||||||
@@ -184,19 +203,29 @@ function RestoreStartMenuForAllUsers {
|
|||||||
if (Test-Path $defaultStartMenuPath) {
|
if (Test-Path $defaultStartMenuPath) {
|
||||||
$defaultStartMenuBinFile = Join-Path $defaultStartMenuPath 'start2.bin'
|
$defaultStartMenuBinFile = Join-Path $defaultStartMenuPath 'start2.bin'
|
||||||
if (Test-Path -LiteralPath $defaultStartMenuBinFile) {
|
if (Test-Path -LiteralPath $defaultStartMenuBinFile) {
|
||||||
try {
|
if ($script:Params.ContainsKey("WhatIf")) {
|
||||||
Remove-Item -LiteralPath $defaultStartMenuBinFile -Force
|
Write-Host "[WhatIf] Remove start2.bin for the default user profile" -ForegroundColor Cyan
|
||||||
$results += [PSCustomObject]@{
|
$results += [PSCustomObject]@{
|
||||||
UserName = 'Default'
|
UserName = 'Default'
|
||||||
Result = $true
|
Result = $true
|
||||||
Message = 'Removed start2.bin for the default user profile.'
|
Message = '[WhatIf] Removed start2.bin for the default user profile.'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch {
|
else {
|
||||||
$results += [PSCustomObject]@{
|
try {
|
||||||
UserName = 'Default'
|
Remove-Item -LiteralPath $defaultStartMenuBinFile -Force
|
||||||
Result = $false
|
$results += [PSCustomObject]@{
|
||||||
Message = "Failed to remove start2.bin for the default user profile. $($_.Exception.Message)"
|
UserName = 'Default'
|
||||||
|
Result = $true
|
||||||
|
Message = 'Removed start2.bin for the default user profile.'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
$results += [PSCustomObject]@{
|
||||||
|
UserName = 'Default'
|
||||||
|
Result = $false
|
||||||
|
Message = "Failed to remove start2.bin for the default user profile. $($_.Exception.Message)"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,11 @@ function RestartExplorer {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($script:Params.ContainsKey("WhatIf")) {
|
||||||
|
Write-Host "[WhatIf] Restart the Windows Explorer process" -ForegroundColor Cyan
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
Write-Host "> Attempting to restart the Windows Explorer process to apply all changes..."
|
Write-Host "> Attempting to restart the Windows Explorer process to apply all changes..."
|
||||||
|
|
||||||
if ($script:Params.ContainsKey("NoRestartExplorer")) {
|
if ($script:Params.ContainsKey("NoRestartExplorer")) {
|
||||||
|
|||||||
@@ -133,6 +133,11 @@ function Restore-RegistryBackupState {
|
|||||||
|
|
||||||
$friendlyTarget = GetFriendlyRegistryBackupTarget -Target ([string]$Backup.Target)
|
$friendlyTarget = GetFriendlyRegistryBackupTarget -Target ([string]$Backup.Target)
|
||||||
|
|
||||||
|
if ($script:Params.ContainsKey("WhatIf")) {
|
||||||
|
Write-Host "[WhatIf] Restore registry backup for $friendlyTarget" -ForegroundColor Cyan
|
||||||
|
return [PSCustomObject]@{ Result = $true }
|
||||||
|
}
|
||||||
|
|
||||||
$restoreAction = {
|
$restoreAction = {
|
||||||
param($normalizedBackup)
|
param($normalizedBackup)
|
||||||
|
|
||||||
@@ -148,9 +153,10 @@ function Restore-RegistryBackupState {
|
|||||||
Write-Host "Restore requires loading target user hive."
|
Write-Host "Restore requires loading target user hive."
|
||||||
Invoke-WithLoadedRestoreHive -Target $Backup.Target -ScriptBlock $restoreAction -ArgumentObject $Backup
|
Invoke-WithLoadedRestoreHive -Target $Backup.Target -ScriptBlock $restoreAction -ArgumentObject $Backup
|
||||||
Write-Host "Restore completed for $friendlyTarget."
|
Write-Host "Restore completed for $friendlyTarget."
|
||||||
return
|
return [PSCustomObject]@{ Result = $true }
|
||||||
}
|
}
|
||||||
|
|
||||||
& $restoreAction $Backup
|
& $restoreAction $Backup
|
||||||
Write-Host "Restore completed for $friendlyTarget."
|
Write-Host "Restore completed for $friendlyTarget."
|
||||||
|
return [PSCustomObject]@{ Result = $true }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,6 +54,11 @@ function DisableStoreSearchSuggestions {
|
|||||||
$userName = [regex]::Match($StoreAppsDatabase, '(?:Users\\)([^\\]+)(?:\\AppData)').Groups[1].Value
|
$userName = [regex]::Match($StoreAppsDatabase, '(?:Users\\)([^\\]+)(?:\\AppData)').Groups[1].Value
|
||||||
if (-not $userName) { $userName = '<unknown>' }
|
if (-not $userName) { $userName = '<unknown>' }
|
||||||
|
|
||||||
|
if ($script:Params.ContainsKey("WhatIf")) {
|
||||||
|
Write-Host "[WhatIf] Disable Microsoft Store search suggestions for user $userName by restricting access to ${StoreAppsDatabase}" -ForegroundColor Cyan
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
# This file doesn't exist in EEA (No Store app suggestions).
|
# This file doesn't exist in EEA (No Store app suggestions).
|
||||||
if (-not (Test-Path -Path $StoreAppsDatabase))
|
if (-not (Test-Path -Path $StoreAppsDatabase))
|
||||||
{
|
{
|
||||||
@@ -132,6 +137,11 @@ function EnableStoreSearchSuggestions {
|
|||||||
$userName = [regex]::Match($StoreAppsDatabase, '(?:Users\\)([^\\]+)(?:\\AppData)').Groups[1].Value
|
$userName = [regex]::Match($StoreAppsDatabase, '(?:Users\\)([^\\]+)(?:\\AppData)').Groups[1].Value
|
||||||
if (-not $userName) { $userName = '<unknown>' }
|
if (-not $userName) { $userName = '<unknown>' }
|
||||||
|
|
||||||
|
if ($script:Params.ContainsKey("WhatIf")) {
|
||||||
|
Write-Host "[WhatIf] Re-enable Microsoft Store search suggestions for user $userName by restoring access to ${StoreAppsDatabase}" -ForegroundColor Cyan
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if (-not (Test-Path -Path $StoreAppsDatabase)) {
|
if (-not (Test-Path -Path $StoreAppsDatabase)) {
|
||||||
Write-Host "Store app database not found for user $userName, nothing to undo"
|
Write-Host "Store app database not found for user $userName, nothing to undo"
|
||||||
return
|
return
|
||||||
@@ -245,7 +255,8 @@ function Test-StoreSearchSuggestionsDisabled {
|
|||||||
$isEveryone = $false
|
$isEveryone = $false
|
||||||
try {
|
try {
|
||||||
$isEveryone = $accessRule.IdentityReference.Translate([System.Security.Principal.SecurityIdentifier]) -eq $everyoneSid
|
$isEveryone = $accessRule.IdentityReference.Translate([System.Security.Principal.SecurityIdentifier]) -eq $everyoneSid
|
||||||
} catch { }
|
}
|
||||||
|
catch { }
|
||||||
|
|
||||||
if ($isEveryone) {
|
if ($isEveryone) {
|
||||||
return $true
|
return $true
|
||||||
|
|||||||
@@ -4,6 +4,12 @@ function EnableWindowsFeature {
|
|||||||
[string]$FeatureName
|
[string]$FeatureName
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if ($script:Params.ContainsKey("WhatIf")) {
|
||||||
|
Write-Host "[WhatIf] Enable Windows feature: $FeatureName" -ForegroundColor Cyan
|
||||||
|
Write-Host ""
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
$result = Invoke-NonBlocking -ScriptBlock {
|
$result = Invoke-NonBlocking -ScriptBlock {
|
||||||
param($name)
|
param($name)
|
||||||
Enable-WindowsOptionalFeature -Online -FeatureName $name -All -NoRestart
|
Enable-WindowsOptionalFeature -Online -FeatureName $name -All -NoRestart
|
||||||
@@ -21,6 +27,12 @@ function DisableWindowsFeature {
|
|||||||
[string]$FeatureName
|
[string]$FeatureName
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if ($script:Params.ContainsKey("WhatIf")) {
|
||||||
|
Write-Host "[WhatIf] Disable Windows feature: $FeatureName" -ForegroundColor Cyan
|
||||||
|
Write-Host ""
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
$result = Invoke-NonBlocking -ScriptBlock {
|
$result = Invoke-NonBlocking -ScriptBlock {
|
||||||
param($name)
|
param($name)
|
||||||
Disable-WindowsOptionalFeature -Online -FeatureName $name -NoRestart
|
Disable-WindowsOptionalFeature -Online -FeatureName $name -NoRestart
|
||||||
|
|||||||
@@ -4,6 +4,11 @@ function SaveCustomAppsListToFile {
|
|||||||
$appsList
|
$appsList
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if ($script:Params.ContainsKey("WhatIf")) {
|
||||||
|
Write-Host "[WhatIf] Save custom apps list to file" -ForegroundColor Cyan
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
$script:SelectedApps = $appsList
|
$script:SelectedApps = $appsList
|
||||||
|
|
||||||
# Create file that stores selected apps if it doesn't exist
|
# Create file that stores selected apps if it doesn't exist
|
||||||
|
|||||||
@@ -1,5 +1,10 @@
|
|||||||
# Saves the current settings, excluding control parameters, to 'LastUsedSettings.json' file
|
# Saves the current settings, excluding control parameters, to 'LastUsedSettings.json' file
|
||||||
function SaveSettings {
|
function SaveSettings {
|
||||||
|
if ($script:Params.ContainsKey("WhatIf")) {
|
||||||
|
Write-Host "[WhatIf] Save settings to LastUsedSettings.json" -ForegroundColor Cyan
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
$settings = @{
|
$settings = @{
|
||||||
"Version" = "1.0"
|
"Version" = "1.0"
|
||||||
"Settings" = @()
|
"Settings" = @()
|
||||||
|
|||||||
@@ -21,7 +21,8 @@ function Show-ImportExportConfigWindow {
|
|||||||
$Owner.Dispatcher.Invoke([action]{ $overlay.Visibility = 'Visible' })
|
$Owner.Dispatcher.Invoke([action]{ $overlay.Visibility = 'Visible' })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch { }
|
}
|
||||||
|
catch { }
|
||||||
|
|
||||||
# Load XAML from schema file
|
# Load XAML from schema file
|
||||||
$schemaPath = $script:ImportExportConfigSchema
|
$schemaPath = $script:ImportExportConfigSchema
|
||||||
@@ -52,7 +53,8 @@ function Show-ImportExportConfigWindow {
|
|||||||
if ($mainCheckBoxStyle) {
|
if ($mainCheckBoxStyle) {
|
||||||
$dlg.Resources.Add([type][System.Windows.Controls.CheckBox], $mainCheckBoxStyle)
|
$dlg.Resources.Add([type][System.Windows.Controls.CheckBox], $mainCheckBoxStyle)
|
||||||
}
|
}
|
||||||
} catch { }
|
}
|
||||||
|
catch { }
|
||||||
|
|
||||||
# Populate named elements
|
# Populate named elements
|
||||||
$dlg.Title = $Title
|
$dlg.Title = $Title
|
||||||
@@ -419,6 +421,12 @@ function Export-Configuration {
|
|||||||
|
|
||||||
Write-Host "Exporting configuration to '$($saveDialog.FileName)'... (Categories: $($categories -join ', '))"
|
Write-Host "Exporting configuration to '$($saveDialog.FileName)'... (Categories: $($categories -join ', '))"
|
||||||
|
|
||||||
|
if ($script:Params.ContainsKey("WhatIf")) {
|
||||||
|
Write-Host "[WhatIf] Export configuration to '$($saveDialog.FileName)'" -ForegroundColor Cyan
|
||||||
|
Show-MessageBox -Message "[WhatIf] Configuration would be exported to this file (no file written)." -Title 'Export Configuration' -Button 'OK' -Icon 'Information' | Out-Null
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if (SaveToFile -Config $config -FilePath $saveDialog.FileName) {
|
if (SaveToFile -Config $config -FilePath $saveDialog.FileName) {
|
||||||
Write-Host "Configuration exported successfully: $($saveDialog.FileName)"
|
Write-Host "Configuration exported successfully: $($saveDialog.FileName)"
|
||||||
Show-MessageBox -Message "Configuration exported successfully." -Title 'Export Configuration' -Button 'OK' -Icon 'Information' | Out-Null
|
Show-MessageBox -Message "Configuration exported successfully." -Title 'Export Configuration' -Button 'OK' -Icon 'Information' | Out-Null
|
||||||
|
|||||||
@@ -953,6 +953,14 @@
|
|||||||
})
|
})
|
||||||
|
|
||||||
$window.Show() | Out-Null
|
$window.Show() | Out-Null
|
||||||
|
|
||||||
|
# If WhatIf mode is enabled, notify the user that no changes will be made
|
||||||
|
if ($script:Params.ContainsKey("WhatIf")) {
|
||||||
|
$window.Dispatcher.BeginInvoke([System.Windows.Threading.DispatcherPriority]::Loaded, [action]{
|
||||||
|
Show-MessageBox -Message "WhatIf mode is enabled. The script will not make any changes to your system in this mode.`n`nYou can observe the actions that would be taken by the script in the console output." -Title 'WhatIf Mode' -Button 'OK' -Icon 'Information' -Owner $window
|
||||||
|
}) | Out-Null
|
||||||
|
}
|
||||||
|
|
||||||
[System.Windows.Threading.Dispatcher]::PushFrame($frame)
|
[System.Windows.Threading.Dispatcher]::PushFrame($frame)
|
||||||
return $null
|
return $null
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,9 +27,16 @@ function Show-RestoreBackupWindow {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Write-Host "User confirmed registry restore for $($backup.Target)."
|
Write-Host "User confirmed registry restore for $($backup.Target)."
|
||||||
Restore-RegistryBackupState -Backup $backup
|
$restoreOpResult = Restore-RegistryBackupState -Backup $backup
|
||||||
$restoreResult.RestoredRegistry = $true
|
if ($restoreOpResult -and $restoreOpResult.Result) {
|
||||||
$successMessage = 'Registry backup restored successfully. Some changes may require a restart to take effect.'
|
$restoreResult.RestoredRegistry = $true
|
||||||
|
if ($script:Params.ContainsKey("WhatIf")) {
|
||||||
|
$successMessage = '[WhatIf] Registry backup would be restored (no changes made).'
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$successMessage = 'Registry backup restored successfully. Some changes may require a restart to take effect.'
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
elseif ($dialogResult.Result -eq 'RestoreStartMenu') {
|
elseif ($dialogResult.Result -eq 'RestoreStartMenu') {
|
||||||
$scope = $dialogResult.StartMenuScope
|
$scope = $dialogResult.StartMenuScope
|
||||||
@@ -67,7 +74,10 @@ function Show-RestoreBackupWindow {
|
|||||||
$warningMessage = "The Start Menu backup was successfully restored for $successCount user(s).`nSome users could not be restored:`n$failureSummary"
|
$warningMessage = "The Start Menu backup was successfully restored for $successCount user(s).`nSome users could not be restored:`n$failureSummary"
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if ($scope -eq 'AllUsers') {
|
if ($script:Params.ContainsKey("WhatIf")) {
|
||||||
|
$successMessage = '[WhatIf] Start Menu backup would be restored (no changes made).'
|
||||||
|
}
|
||||||
|
elseif ($scope -eq 'AllUsers') {
|
||||||
$successMessage = "The Start Menu backup was successfully restored for all users. The changes will apply the next time users sign in."
|
$successMessage = "The Start Menu backup was successfully restored for all users. The changes will apply the next time users sign in."
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|||||||
@@ -203,6 +203,11 @@ function Invoke-RegistryOperationsFromRegFile {
|
|||||||
$operations = @(Get-RegFileOperations -regFilePath $RegFilePath)
|
$operations = @(Get-RegFileOperations -regFilePath $RegFilePath)
|
||||||
$totalOperations = $operations.Count
|
$totalOperations = $operations.Count
|
||||||
|
|
||||||
|
if ($script:Params.ContainsKey("WhatIf")) {
|
||||||
|
Write-Host "[WhatIf] Apply $totalOperations registry changes from '$RegFilePath'" -ForegroundColor Cyan
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
foreach ($operation in $operations) {
|
foreach ($operation in $operations) {
|
||||||
try {
|
try {
|
||||||
Invoke-RegistryOperation -Operation $operation -RegFilePath $RegFilePath
|
Invoke-RegistryOperation -Operation $operation -RegFilePath $RegFilePath
|
||||||
|
|||||||
@@ -81,3 +81,4 @@ function Get-RegistryFilePathForFeature {
|
|||||||
|
|
||||||
return Join-Path $script:RegfilesPath $RegistryKey
|
return Join-Path $script:RegfilesPath $RegistryKey
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -221,6 +221,15 @@ else {
|
|||||||
Start-Transcript -Path $script:DefaultLogPath -Append -IncludeInvocationHeader -Force | Out-Null
|
Start-Transcript -Path $script:DefaultLogPath -Append -IncludeInvocationHeader -Force | Out-Null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Check if the device is domain-joined and warn the user (Group Policy may override changes)
|
||||||
|
try {
|
||||||
|
$computerSystem = Get-CimInstance Win32_ComputerSystem -ErrorAction SilentlyContinue
|
||||||
|
if ($null -ne $computerSystem -and $computerSystem.PartOfDomain) {
|
||||||
|
Write-Warning "This machine is domain-joined. Group Policy may override changes made by Win11Debloat."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch { }
|
||||||
|
|
||||||
# Check if script has all required files
|
# Check if script has all required files
|
||||||
if (-not ((Test-Path $script:DefaultSettingsFilePath) -and (Test-Path $script:AppsListFilePath) -and (Test-Path $script:RegfilesPath) -and (Test-Path $script:AssetsPath) -and (Test-Path $script:AppSelectionSchema) -and (Test-Path $script:ApplyChangesWindowSchema) -and (Test-Path $script:SharedStylesSchema) -and (Test-Path $script:BubbleHintSchema) -and (Test-Path $script:RestoreBackupWindowSchema) -and (Test-Path $script:FeaturesFilePath))) {
|
if (-not ((Test-Path $script:DefaultSettingsFilePath) -and (Test-Path $script:AppsListFilePath) -and (Test-Path $script:RegfilesPath) -and (Test-Path $script:AssetsPath) -and (Test-Path $script:AppSelectionSchema) -and (Test-Path $script:ApplyChangesWindowSchema) -and (Test-Path $script:SharedStylesSchema) -and (Test-Path $script:BubbleHintSchema) -and (Test-Path $script:RestoreBackupWindowSchema) -and (Test-Path $script:FeaturesFilePath))) {
|
||||||
Write-Error "Win11Debloat is unable to find required files, please ensure all script files are present"
|
Write-Error "Win11Debloat is unable to find required files, please ensure all script files are present"
|
||||||
@@ -494,7 +503,11 @@ if ((-not $script:Params.Count) -or $RunDefaults -or $RunDefaultsLite -or $RunSa
|
|||||||
try {
|
try {
|
||||||
$result = Show-MainWindow
|
$result = Show-MainWindow
|
||||||
|
|
||||||
Stop-Transcript
|
try {
|
||||||
|
Stop-Transcript
|
||||||
|
}
|
||||||
|
catch { }
|
||||||
|
|
||||||
Exit
|
Exit
|
||||||
}
|
}
|
||||||
catch {
|
catch {
|
||||||
|
|||||||
Reference in New Issue
Block a user