fix: improve error handling for registry file imports and telemetry scheduled tasks

This commit is contained in:
Jeffrey
2026-08-22 19:29:54 +02:00
parent c921730703
commit b7f612f36e
5 changed files with 173 additions and 93 deletions
+1 -1
View File
@@ -11,6 +11,7 @@ function Import-RegistryFile {
$path $path
) )
try {
Write-Host $message Write-Host $message
$usesOfflineHive = $script:Params.ContainsKey("Sysprep") -or $script:Params.ContainsKey("User") $usesOfflineHive = $script:Params.ContainsKey("Sysprep") -or $script:Params.ContainsKey("User")
@@ -102,7 +103,6 @@ function Import-RegistryFile {
return $true return $true
} }
try {
if ($usesOfflineHive) { if ($usesOfflineHive) {
# Sysprep targets Default user, User targets the specified user. Logged-in users already have their hive mounted under HKU\<SID>. # Sysprep targets Default user, User targets the specified user. Logged-in users already have their hive mounted under HKU\<SID>.
$targetUserName = if ($script:Params.ContainsKey("Sysprep")) { "Default" } else { $script:Params.Item("User") } $targetUserName = if ($script:Params.ContainsKey("Sysprep")) { "Default" } else { $script:Params.Item("User") }
+18 -2
View File
@@ -55,7 +55,15 @@ function Disable-TelemetryScheduledTasks {
$result = Invoke-NonBlocking -ScriptBlock { $result = Invoke-NonBlocking -ScriptBlock {
param($path, $name) param($path, $name)
Import-Module ScheduledTasks -ErrorAction SilentlyContinue Import-Module ScheduledTasks -ErrorAction SilentlyContinue
$taskObj = Get-ScheduledTask -TaskPath $path -TaskName $name -ErrorAction SilentlyContinue try {
$taskObj = Get-ScheduledTask -TaskPath $path -TaskName $name -ErrorAction Stop
}
catch {
if ($_.CategoryInfo.Category -eq [System.Management.Automation.ErrorCategory]::ObjectNotFound) {
return @{ Success = $true; Status = 'NotFound' }
}
return @{ Success = $false; Status = 'Error'; Error = $_.Exception.Message }
}
if (-not $taskObj) { if (-not $taskObj) {
return @{ Success = $true; Status = 'NotFound' } return @{ Success = $true; Status = 'NotFound' }
} }
@@ -121,7 +129,15 @@ function Enable-TelemetryScheduledTasks {
$result = Invoke-NonBlocking -ScriptBlock { $result = Invoke-NonBlocking -ScriptBlock {
param($path, $name) param($path, $name)
Import-Module ScheduledTasks -ErrorAction SilentlyContinue Import-Module ScheduledTasks -ErrorAction SilentlyContinue
$taskObj = Get-ScheduledTask -TaskPath $path -TaskName $name -ErrorAction SilentlyContinue try {
$taskObj = Get-ScheduledTask -TaskPath $path -TaskName $name -ErrorAction Stop
}
catch {
if ($_.CategoryInfo.Category -eq [System.Management.Automation.ErrorCategory]::ObjectNotFound) {
return @{ Success = $true; Status = 'NotFound' }
}
return @{ Success = $false; Status = 'Error'; Error = $_.Exception.Message }
}
if (-not $taskObj) { if (-not $taskObj) {
return @{ Success = $true; Status = 'NotFound' } return @{ Success = $true; Status = 'NotFound' }
} }
+12
View File
@@ -67,6 +67,18 @@ Describe 'Test-ConfigConsistency' {
Test-ConfigConsistency -Config $config | Should -Match 'Apps entries must be strings' Test-ConfigConsistency -Config $config | Should -Match 'Apps entries must be strings'
} }
It 'reports an error for malformed tweak entries' {
$config = [PSCustomObject]@{ Version = '1.0'; Tweaks = @(@{ Value = $true }) }
Test-ConfigConsistency -Config $config | Should -Match 'Tweaks entries must contain Name and Value properties'
}
It 'reports an error for deployment entries missing a required property' {
$config = [PSCustomObject]@{ Version = '1.0'; Deployment = @(@{ Name = 'CreateRestorePoint' }) }
Test-ConfigConsistency -Config $config | Should -Match 'Deployment entries must contain Name and Value properties'
}
It 'reports an error for nonnumeric deployment indexes' { It 'reports an error for nonnumeric deployment indexes' {
$config = [PSCustomObject]@{ $config = [PSCustomObject]@{
Version = '1.0' Version = '1.0'
+7
View File
@@ -26,6 +26,13 @@ Describe 'Import-RegistryFile' {
Should -Invoke Invoke-NonBlocking -Times 0 -Exactly Should -Invoke Invoke-NonBlocking -Times 0 -Exactly
} }
It 'returns false when registry file resolution throws' {
Mock Get-RegistryFilePathForFeature { throw 'path resolution failed' }
Import-RegistryFile -message 'Apply' -path 'feature.reg' | Should -BeFalse
Should -Invoke Invoke-NonBlocking -Times 0 -Exactly
}
It 'uses the PowerShell writer only in WhatIf mode' { It 'uses the PowerShell writer only in WhatIf mode' {
$script:Params = @{ WhatIf = $true } $script:Params = @{ WhatIf = $true }
Import-RegistryFile -message 'Apply' -path 'feature.reg' | Should -BeTrue Import-RegistryFile -message 'Apply' -path 'feature.reg' | Should -BeTrue
+45
View File
@@ -95,6 +95,35 @@ Describe 'Disable-TelemetryScheduledTasks' {
$result.Error | Should -Match 'access denied' $result.Error | Should -Match 'access denied'
} }
It 'returns an error when scheduled-task lookup fails' {
Mock Invoke-NonBlocking {
param($ScriptBlock, $ArgumentList)
$script:taskBlock = $ScriptBlock
$script:taskArguments = $ArgumentList
}
Mock Import-Module {}
Mock Get-ScheduledTask { throw 'scheduler unavailable' }
Disable-TelemetryScheduledTasks
$result = & $script:taskBlock @script:taskArguments
$result.Status | Should -Be 'Error'
$result.Error | Should -Match 'scheduler unavailable'
}
It 'treats an absent scheduled task as not found' {
Mock Invoke-NonBlocking {
param($ScriptBlock, $ArgumentList)
$script:taskBlock = $ScriptBlock
$script:taskArguments = $ArgumentList
}
Mock Import-Module {}
Mock Get-ScheduledTask { $null }
Disable-TelemetryScheduledTasks
(& $script:taskBlock @script:taskArguments).Status | Should -Be 'NotFound'
}
It 'reports <Status> task results' -ForEach @( It 'reports <Status> task results' -ForEach @(
@{ Status = 'Disabled'; Expected = 'Disabled Scheduled Task' } @{ Status = 'Disabled'; Expected = 'Disabled Scheduled Task' }
@{ Status = 'AlreadyDisabled'; Expected = 'already disabled' } @{ Status = 'AlreadyDisabled'; Expected = 'already disabled' }
@@ -175,6 +204,22 @@ Describe 'Enable-TelemetryScheduledTasks' {
Should -Invoke Enable-ScheduledTask -Times 1 -Exactly -ParameterFilter { $TaskPath -eq '\Microsoft\Windows\Test\' -and $TaskName -eq 'Second' } Should -Invoke Enable-ScheduledTask -Times 1 -Exactly -ParameterFilter { $TaskPath -eq '\Microsoft\Windows\Test\' -and $TaskName -eq 'Second' }
} }
It 'returns an error when scheduled-task lookup fails' {
Mock Invoke-NonBlocking {
param($ScriptBlock, $ArgumentList)
$script:taskBlock = $ScriptBlock
$script:taskArguments = $ArgumentList
}
Mock Import-Module {}
Mock Get-ScheduledTask { throw 'scheduler unavailable' }
Enable-TelemetryScheduledTasks
$result = & $script:taskBlock @script:taskArguments
$result.Status | Should -Be 'Error'
$result.Error | Should -Match 'scheduler unavailable'
}
It 'reports <Status> task results' -ForEach @( It 'reports <Status> task results' -ForEach @(
@{ Status = 'Enabled'; Expected = 'Enabled Scheduled Task' } @{ Status = 'Enabled'; Expected = 'Enabled Scheduled Task' }
@{ Status = 'AlreadyEnabled'; Expected = 'already enabled' } @{ Status = 'AlreadyEnabled'; Expected = 'already enabled' }