From 24a6f1bcf84b82587068dec557123804bfbc0aa0 Mon Sep 17 00:00:00 2001 From: Jeffrey <9938813+Raphire@users.noreply.github.com> Date: Mon, 11 May 2026 19:14:08 +0200 Subject: [PATCH] Fix capture and restore of signed dword/qword registry values Co-authored-by: Copilot --- .../BackupRegistrySnapshotCapture.ps1 | 19 +++++++++++++------ Scripts/Features/ExecuteChanges.ps1 | 7 ++++++- .../Features/RestoreRegistryApplyState.ps1 | 10 ++++++++-- 3 files changed, 27 insertions(+), 9 deletions(-) diff --git a/Scripts/Features/BackupRegistrySnapshotCapture.ps1 b/Scripts/Features/BackupRegistrySnapshotCapture.ps1 index fc77837..2d0893d 100644 --- a/Scripts/Features/BackupRegistrySnapshotCapture.ps1 +++ b/Scripts/Features/BackupRegistrySnapshotCapture.ps1 @@ -226,12 +226,19 @@ function Convert-RegistryValueToSnapshot { $valueKind = $RegistryKey.GetValueKind($ValueName) $value = $RegistryKey.GetValue($ValueName, $null, [Microsoft.Win32.RegistryValueOptions]::DoNotExpandEnvironmentNames) - $normalizedValue = switch ($valueKind) { - ([Microsoft.Win32.RegistryValueKind]::Binary) { @($value | ForEach-Object { [int]$_ }) } - ([Microsoft.Win32.RegistryValueKind]::MultiString) { @($value) } - ([Microsoft.Win32.RegistryValueKind]::DWord) { [uint32]$value } - ([Microsoft.Win32.RegistryValueKind]::QWord) { [uint64]$value } - default { if ($null -ne $value) { [string]$value } else { $null } } + try { + $normalizedValue = switch ($valueKind) { + ([Microsoft.Win32.RegistryValueKind]::Binary) { @($value | ForEach-Object { [int]$_ }) } + ([Microsoft.Win32.RegistryValueKind]::MultiString) { @($value) } + ([Microsoft.Win32.RegistryValueKind]::DWord) { [BitConverter]::ToUInt32([BitConverter]::GetBytes([int32]$value), 0) } + ([Microsoft.Win32.RegistryValueKind]::QWord) { [BitConverter]::ToUInt64([BitConverter]::GetBytes([int64]$value), 0) } + default { if ($null -ne $value) { [string]$value } else { $null } } + } + } + catch { + $valueType = if ($null -ne $value) { $value.GetType().FullName } else { '' } + $valueForLog = if ($null -eq $value) { '' } elseif ($value -is [array]) { ($value -join ',') } else { [string]$value } + throw "Failed to normalize registry value for backup. Key='$($RegistryKey.Name)' Name='$ValueName' Kind='$valueKind' RawType='$valueType' RawValue='$valueForLog'. InnerError: $($_.Exception.Message)" } return @{ diff --git a/Scripts/Features/ExecuteChanges.ps1 b/Scripts/Features/ExecuteChanges.ps1 index 4d155b4..772627a 100644 --- a/Scripts/Features/ExecuteChanges.ps1 +++ b/Scripts/Features/ExecuteChanges.ps1 @@ -170,7 +170,12 @@ function ExecuteAllChanges { } Write-Host "> Creating registry backup..." - New-RegistrySettingsBackup -ActionableKeys $actionableKeys | Out-Null + try { + New-RegistrySettingsBackup -ActionableKeys $actionableKeys | Out-Null + } + catch { + throw "Registry backup failed before applying changes. $($_.Exception.Message)" + } } # Create restore point if requested (CLI only - GUI handles this separately) diff --git a/Scripts/Features/RestoreRegistryApplyState.ps1 b/Scripts/Features/RestoreRegistryApplyState.ps1 index 49a92f9..705dbb7 100644 --- a/Scripts/Features/RestoreRegistryApplyState.ps1 +++ b/Scripts/Features/RestoreRegistryApplyState.ps1 @@ -157,8 +157,14 @@ function Convert-RegistryValueDataFromBackup { ) switch ($Kind) { - ([Microsoft.Win32.RegistryValueKind]::DWord) { return [uint32]$Data } - ([Microsoft.Win32.RegistryValueKind]::QWord) { return [uint64]$Data } + ([Microsoft.Win32.RegistryValueKind]::DWord) { + $unsigned = [uint32]$Data + return [BitConverter]::ToInt32([BitConverter]::GetBytes($unsigned), 0) + } + ([Microsoft.Win32.RegistryValueKind]::QWord) { + $unsigned = [uint64]$Data + return [BitConverter]::ToInt64([BitConverter]::GetBytes($unsigned), 0) + } ([Microsoft.Win32.RegistryValueKind]::MultiString) { return @($Data | ForEach-Object { [string]$_ }) } ([Microsoft.Win32.RegistryValueKind]::Binary) { $bytes = Convert-BackupDataToByteArray -Data $Data