Improve registry backup safety and add optional backup skipping (#710)

This commit is contained in:
Jeffrey
2026-07-25 20:05:49 +02:00
committed by GitHub
parent 68cacfce89
commit 32cedaf65d
30 changed files with 1603 additions and 43 deletions
+53 -7
View File
@@ -5,7 +5,7 @@ BeforeAll {
function Enable-TelemetryScheduledTasks {}
function Generate-AppsList { @() }
function Get-FriendlyTargetUserName { 'current user' }
function EnableStoreSearchSuggestionsForAllUsers {}
function Set-StoreSearchSuggestionsEnabledForAllUsers {}
function Set-StoreSearchSuggestionsEnabled { param($StoreAppsDatabase) }
function Get-StoreAppsDatabasePathForUser { param($UserName) 'store.db' }
function Get-UserName { 'Alice' }
@@ -16,7 +16,7 @@ BeforeAll {
function Get-StartMenuBinPathForUser { param($UserName) 'start.bin' }
function Replace-StartMenu { param($startMenuBinFile, $startMenuTemplate) }
function Replace-StartMenuForAllUsers { param($startMenuTemplate) }
function DisableStoreSearchSuggestionsForAllUsers {}
function Set-StoreSearchSuggestionsDisabledForAllUsers {}
function Set-StoreSearchSuggestionsDisabled { param($StoreAppsDatabase) }
. (Join-Path $PSScriptRoot '..\Scripts\Features\Invoke-Changes.ps1')
@@ -70,11 +70,11 @@ Describe 'Invoke-FeatureApply' {
Mock Get-UserName { 'Alice' }
Mock Replace-StartMenu {}
Mock Replace-StartMenuForAllUsers {}
Mock DisableStoreSearchSuggestionsForAllUsers {}
Mock Set-StoreSearchSuggestionsDisabledForAllUsers {}
Mock Set-StoreSearchSuggestionsDisabled {}
Mock Get-StoreAppsDatabasePathForUser { 'store.db' }
Mock Get-Process { @() }
Mock Stop-Process {}
Mock Stop-Process { param($InputObject) }
Mock Write-Host {}
}
@@ -132,6 +132,15 @@ Describe 'Invoke-FeatureApply' {
Should -Invoke Stop-Process -Times 0 -Exactly
}
It 'stops widget processes before removing widget packages' {
$widget = [PSCustomObject]@{ Name = 'WidgetService' }
Mock Get-Process { $widget }
Invoke-FeatureApply -FeatureId 'DisableWidgets'
Should -Invoke Stop-Process -Times 1 -Exactly
}
It 'stops widget processes without a confirmation prompt' {
Mock Get-Process { [PSCustomObject]@{ Name = 'Widgets' } }
@@ -173,7 +182,15 @@ Describe 'Invoke-FeatureApply' {
$script:Params = @{ Sysprep = $true }
Invoke-FeatureApply -FeatureId 'DisableStoreSearchSuggestions'
Should -Invoke DisableStoreSearchSuggestionsForAllUsers -Times 1 -Exactly
Should -Invoke Set-StoreSearchSuggestionsDisabledForAllUsers -Times 1 -Exactly
Should -Invoke Set-StoreSearchSuggestionsDisabled -Times 0 -Exactly
}
It 'does not update Store search suggestions when the current user database cannot be resolved' {
Mock Get-StoreAppsDatabasePathForUser { $null }
Invoke-FeatureApply -FeatureId 'DisableStoreSearchSuggestions'
Should -Invoke Set-StoreSearchSuggestionsDisabled -Times 0 -Exactly
}
}
@@ -235,6 +252,15 @@ Describe 'Invoke-UndoFeatures' {
Should -Invoke Import-RegistryFile -Times 0 -Exactly
Should -Invoke Invoke-FeatureUndo -Times 2 -Exactly
}
It 'stops before undoing when cancellation is requested' {
$script:CancelRequested = $true
Invoke-UndoFeatures -FeatureIds @('RegistryUndo') -StartStep 1 -TotalSteps 1
Should -Invoke Import-RegistryFile -Times 0 -Exactly
Should -Invoke Invoke-FeatureUndo -Times 0 -Exactly
}
}
Describe 'Invoke-FeatureUndo' {
@@ -246,7 +272,7 @@ Describe 'Invoke-FeatureUndo' {
DisableTelemetry = [PSCustomObject]@{}
DisableStoreSearchSuggestions = [PSCustomObject]@{}
}
Mock EnableStoreSearchSuggestionsForAllUsers {}
Mock Set-StoreSearchSuggestionsEnabledForAllUsers {}
Mock Set-StoreSearchSuggestionsEnabled {}
Mock Get-StoreAppsDatabasePathForUser { 'store.db' }
Mock Get-UserName { 'Alice' }
@@ -261,7 +287,7 @@ Describe 'Invoke-FeatureUndo' {
) {
$script:Params = $Params
Invoke-FeatureUndo -FeatureId 'DisableStoreSearchSuggestions'
Should -Invoke EnableStoreSearchSuggestionsForAllUsers -Times $AllUsers -Exactly
Should -Invoke Set-StoreSearchSuggestionsEnabledForAllUsers -Times $AllUsers -Exactly
Should -Invoke Set-StoreSearchSuggestionsEnabled -Times $CurrentUser -Exactly -ParameterFilter { $StoreAppsDatabase -eq 'store.db' }
}
@@ -323,6 +349,16 @@ Describe 'Invoke-AllChanges' {
Should -Invoke Invoke-SystemRestorePoint -Times 0 -Exactly
}
It 'does not create a registry backup when explicitly skipped' {
$script:Params['SkipRegistryBackup'] = $true
Invoke-AllChanges
Should -Invoke New-RegistrySettingsBackup -Times 0 -Exactly
Should -Invoke Invoke-ApplyFeatures -Times 1 -Exactly
Should -Invoke Invoke-UndoFeatures -Times 1 -Exactly
}
It 'does not run when cancellation was already requested' {
$script:CancelRequested = $true
Invoke-AllChanges
@@ -363,4 +399,14 @@ Describe 'Invoke-AllChanges' {
Invoke-AllChanges
$script:order | Should -Be @('restore-point', 'apply')
}
It 'reports registry import failures after all requested work completes' {
$script:Params = @{ CustomApply = $true }
$script:UndoParams = @{}
Mock Invoke-ApplyFeatures { $script:RegistryImportFailures = 2 }
Invoke-AllChanges
Should -Invoke Write-Host -Times 1 -Exactly -ParameterFilter { $Object -match '2 registry import change' }
}
}