diff --git a/playbook/shopfloor-setup/gea-shopfloor-waxtrace/scripts/Install-FormtracepakSettings.ps1 b/playbook/shopfloor-setup/gea-shopfloor-waxtrace/scripts/Install-FormtracepakSettings.ps1 index 61c9c89..c3513e0 100755 --- a/playbook/shopfloor-setup/gea-shopfloor-waxtrace/scripts/Install-FormtracepakSettings.ps1 +++ b/playbook/shopfloor-setup/gea-shopfloor-waxtrace/scripts/Install-FormtracepakSettings.ps1 @@ -444,41 +444,64 @@ if ($RestoreRegistry) { # If not resolved, skip HKEY_USERS .reg files. $regFiles = Get-ChildItem -Path $regDir -Filter '*.reg' -ErrorAction SilentlyContinue foreach ($rf in $regFiles) { - $isUserReg = ($rf.Name -match 'HKEY_USERS') + # Decide per-user vs HKLM by the .reg CONTENT root, NOT the filename. + # The backup names files after the source path, so an operator pref + # captured via HKCU:\ lands in a file named "HKCU_..." with content + # root HKEY_CURRENT_USER - which a filename match on 'HKEY_USERS' + # misses entirely. Read the content once and classify by its root(s): + # [HKEY_CURRENT_USER... -> per-user, remap root to HKEY_USERS\ + # [HKEY_USERS\... -> per-user, remap srcSid -> targetSid + # [HKEY_LOCAL_MACHINE... -> HKLM + $content = $null + try { $content = Get-Content -LiteralPath $rf.FullName -Raw } catch { + Write-Warning " [ERR] Could not read $($rf.Name): $_ - skipping" + $counters.Errors++ + continue + } + $hasCU = $content -match '\[HKEY_CURRENT_USER' + $hasHKU = $content -match '\[HKEY_USERS\\S-1-5-21' + $isUserReg = ($hasCU -or $hasHKU) + if ($HKEYUsersOnly -and -not $isUserReg) { Write-Host " [SKIP] HKEY_USERS-only mode, skipping HKLM .reg: $($rf.Name)" -ForegroundColor DarkGray $counters.Skipped++ continue } if ($isUserReg -and -not $targetSid) { - Write-Host " [SKIP] HKEY_USERS .reg file - target SID not resolved: $($rf.Name)" -ForegroundColor DarkGray + Write-Host " [SKIP] per-user .reg - target SID not resolved: $($rf.Name)" -ForegroundColor DarkGray $counters.Skipped++ continue } $importPath = $rf.FullName if ($isUserReg) { - # Read .reg, detect src SID (first S-1-5-21-* match), substitute - # target SID, write to a temp file. reg.exe import the temp. + # Rewrite the root(s) so the import lands in the TARGET user's hive, + # then write a temp UTF-16-LE file (reg.exe import requires Unicode). try { - $content = Get-Content -LiteralPath $rf.FullName -Raw - $m = [regex]::Match($content, $srcSidRegex) - if ($m.Success) { - $srcSid = $m.Value - if ($srcSid -ne $targetSid) { - $newContent = $content -replace [regex]::Escape($srcSid), $targetSid - $tmp = Join-Path $env:TEMP ("rewrite-" + $rf.Name) - # .reg files MUST be UTF-16-LE (Unicode) for reg.exe import. - # Set-Content -Encoding Unicode does that. - Set-Content -LiteralPath $tmp -Value $newContent -Encoding Unicode -Force - $importPath = $tmp - Write-Host " [REMAP] $($rf.Name): SID $srcSid -> $targetSid" + $newContent = $content + if ($hasHKU) { + # HKEY_USERS\ -> HKEY_USERS\ + $m = [regex]::Match($content, $srcSidRegex) + if ($m.Success -and $m.Value -ne $targetSid) { + $newContent = $newContent -replace [regex]::Escape($m.Value), $targetSid + Write-Host " [REMAP] $($rf.Name): SID $($m.Value) -> $targetSid" } + } + if ($hasCU) { + # HKEY_CURRENT_USER -> HKEY_USERS\ (this is the + # case the old filename-based logic dropped on the floor). + $newContent = $newContent -replace '\[HKEY_CURRENT_USER', "[HKEY_USERS\$targetSid" + Write-Host " [REMAP] $($rf.Name): HKEY_CURRENT_USER -> HKEY_USERS\$targetSid" + } + if ($newContent -ne $content) { + $tmp = Join-Path $env:TEMP ("rewrite-" + $rf.Name) + Set-Content -LiteralPath $tmp -Value $newContent -Encoding Unicode -Force + $importPath = $tmp } else { - Write-Host " [INFO] No SID found in $($rf.Name) - importing as-is" -ForegroundColor DarkGray + Write-Host " [INFO] $($rf.Name): per-user root already matches target - importing as-is" -ForegroundColor DarkGray } } catch { - Write-Warning " [ERR] SID rewrite failed for $($rf.Name): $_ - skipping" + Write-Warning " [ERR] root rewrite failed for $($rf.Name): $_ - skipping" $counters.Errors++ continue }