diff --git a/Scripts/Features/BackupRegistrySnapshotCapture.ps1 b/Scripts/Features/BackupRegistrySnapshotCapture.ps1 index 29cc470..fc77837 100644 --- a/Scripts/Features/BackupRegistrySnapshotCapture.ps1 +++ b/Scripts/Features/BackupRegistrySnapshotCapture.ps1 @@ -1,12 +1,13 @@ function Get-RegistryBackupCapturePlans { param( [Parameter(Mandatory)] - [object[]]$SelectedRegistryFeatures + [object[]]$SelectedRegistryFeatures, + [switch]$UseSysprepRegFiles ) $planMap = @{} foreach ($feature in $SelectedRegistryFeatures) { - $regFilePath = Get-RegistryFilePathForFeature -Feature $feature + $regFilePath = Get-RegistryFilePathForFeature -Feature $feature -UseSysprepRegFiles:$UseSysprepRegFiles if (-not (Test-Path $regFilePath)) { throw "Unable to find registry file for backup: $($feature.RegistryKey) ($regFilePath)" } diff --git a/Scripts/Features/RegistryBackupValidation.ps1 b/Scripts/Features/RegistryBackupValidation.ps1 index 103b8b3..b3c8624 100644 --- a/Scripts/Features/RegistryBackupValidation.ps1 +++ b/Scripts/Features/RegistryBackupValidation.ps1 @@ -96,6 +96,8 @@ function Test-RegistryBackupMatchesSelectedFeatures { [AllowEmptyCollection()] [string[]]$SelectedFeatureIds, [Parameter(Mandatory)] + [string]$Target, + [Parameter(Mandatory)] [AllowEmptyCollection()] [object[]]$RegistryKeys ) @@ -108,10 +110,11 @@ function Test-RegistryBackupMatchesSelectedFeatures { } $selectedRegistryFeatures = @(Get-SelectedRegistryFeaturesForBackupValidation -SelectedFeatureIds @($SelectedFeatureIds) -Errors $errors) + $useSysprepRegFiles = ($Target -eq 'DefaultUserProfile') -or ($Target -like 'User:*') $capturePlans = @() if ($errors.Count -eq 0 -and $selectedRegistryFeatures.Count -gt 0) { - $capturePlans = @(Get-RegistryBackupCapturePlans -SelectedRegistryFeatures @($selectedRegistryFeatures)) + $capturePlans = @(Get-RegistryBackupCapturePlans -SelectedRegistryFeatures @($selectedRegistryFeatures) -UseSysprepRegFiles:$useSysprepRegFiles) } $planMap = New-RegistryBackupAllowListPlanMap -CapturePlans @($capturePlans) diff --git a/Scripts/Features/RestoreRegistryBackup.ps1 b/Scripts/Features/RestoreRegistryBackup.ps1 index 359b3d2..3ae84af 100644 --- a/Scripts/Features/RestoreRegistryBackup.ps1 +++ b/Scripts/Features/RestoreRegistryBackup.ps1 @@ -87,7 +87,7 @@ function Normalize-RegistryBackup { $errors.Add([string]$selectedFeatureParseError) } - $allowListValidationErrors = @(Test-RegistryBackupMatchesSelectedFeatures -SelectedFeatureIds @($selectedFeatures) -RegistryKeys @($normalizedKeys)) + $allowListValidationErrors = @(Test-RegistryBackupMatchesSelectedFeatures -SelectedFeatureIds @($selectedFeatures) -Target $normalizedTarget -RegistryKeys @($normalizedKeys)) foreach ($allowListValidationError in $allowListValidationErrors) { $errors.Add([string]$allowListValidationError) } diff --git a/Scripts/Helpers/RegistryPathHelpers.ps1 b/Scripts/Helpers/RegistryPathHelpers.ps1 index c37c099..7795245 100644 --- a/Scripts/Helpers/RegistryPathHelpers.ps1 +++ b/Scripts/Helpers/RegistryPathHelpers.ps1 @@ -4,13 +4,47 @@ function Split-RegistryPath { [string]$path ) - if ($path -notmatch '^(?HKEY_[^\\]+)(?:\\(?.*))?$') { + $normalizedPath = [string]$path + if ([string]::IsNullOrWhiteSpace($normalizedPath)) { return $null } + $normalizedPath = $normalizedPath.Trim().Replace('/', '\') + if ([string]::IsNullOrWhiteSpace($normalizedPath)) { + return $null + } + + if ($normalizedPath -notmatch '^(?HKEY_[^\\]+)(?:\\(?.*))?$') { + return $null + } + + $hiveName = [string]$matches.hive + + $normalizedSubKey = if ($null -ne $matches.subKey) { + ([string]$matches.subKey).Trim('\\') + } + else { + $null + } + + if ($hiveName.Equals('HKEY_USERS', [System.StringComparison]::OrdinalIgnoreCase) -and -not [string]::IsNullOrWhiteSpace($normalizedSubKey)) { + if ($normalizedSubKey -match '^(?[^\\]+)(?:\\(?.*))?$') { + $mountName = [string]$matches.mount + if ($mountName.Equals('.DEFAULT', [System.StringComparison]::OrdinalIgnoreCase)) { + $remainingSubKey = if ($matches.rest) { [string]$matches.rest } else { '' } + if ([string]::IsNullOrWhiteSpace($remainingSubKey)) { + $normalizedSubKey = 'Default' + } + else { + $normalizedSubKey = "Default\$remainingSubKey" + } + } + } + } + return [PSCustomObject]@{ - Hive = $matches.hive - SubKey = $matches.subKey + Hive = $hiveName + SubKey = $normalizedSubKey } } @@ -33,10 +67,12 @@ function Get-RegistryRootKey { function Get-RegistryFilePathForFeature { param( [Parameter(Mandatory)] - $Feature + $Feature, + [switch]$UseSysprepRegFiles ) - if ($script:Params.ContainsKey('Sysprep') -or $script:Params.ContainsKey('User')) { + $useSysprepLayout = $UseSysprepRegFiles -or $script:Params.ContainsKey('Sysprep') -or $script:Params.ContainsKey('User') + if ($useSysprepLayout) { return Join-Path (Join-Path $script:RegfilesPath 'Sysprep') $Feature.RegistryKey }