# Test-RegExport.ps1 # # Exercises Backup-NtlarsSettings.ps1's Export-DncToReg against MOCK registry # keys, so the formatting can be verified on a machine with no registry (a # Linux dev box running PowerShell Core, for instance). # # Why this exists: bad escaping or a wrong dword format produces a .reg that # looks fine, imports without complaint, and only reveals itself when a tech # restores a machine and the settings are subtly wrong. That failure is far too # late and far too expensive, so the formatting gets tested away from the bay. # # Writes the generated .reg to -OutFile so the ShopDB-side Python codec can # parse it in the same run and confirm both ends agree. # # pwsh -NoProfile -File Test-RegExport.ps1 -OutFile /tmp/mock.reg param( [string]$OutFile = './mock-export.reg' ) $ErrorActionPreference = 'Stop' . (Join-Path $PSScriptRoot 'Backup-NtlarsSettings.ps1') function New-MockKey { <# A stand-in for a Microsoft.Win32.RegistryKey. PowerShell is duck-typed, so Export-DncToReg only needs .Name, .GetValueNames(), .GetValueKind() and .GetValue(). #> param( [Parameter(Mandatory)][string]$Name, [Parameter(Mandatory)][hashtable]$Values # name -> @{ Kind; Data } ) $key = [pscustomobject]@{ Name = $Name; _values = $Values } $key | Add-Member ScriptMethod GetValueNames { $this._values.Keys } -Force $key | Add-Member ScriptMethod GetValueKind { param($n) $this._values[$n].Kind } -Force $key | Add-Member ScriptMethod GetValue { param($n) $this._values[$n].Data } -Force return $key } $root = 'HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\GE Aircraft Engines\DNC' $keys = @( New-MockKey -Name $root -Values @{ 'COMPUTERNAME' = @{ Kind = 'String'; Data = 'GGBX0NH3ESF' } } New-MockKey -Name "$root\General" -Values @{ 'MachineNo' = @{ Kind = 'String'; Data = '3204' } 'Cnc' = @{ Kind = 'String'; Data = 'OKUMA' } 'HostType' = @{ Kind = 'String'; Data = 'WILM' } } New-MockKey -Name "$root\Btr" -Values @{ 'BTR Rate' = @{ Kind = 'String'; Data = '300' } 'Auto Rewind' = @{ Kind = 'String'; Data = 'YES' } 'CmntLag' = @{ Kind = 'DWord'; Data = 0 } 'BigCount' = @{ Kind = 'DWord'; Data = 4294967295 } } # The nasty cases: characters that must be escaped, and the wide/binary # value kinds that do not occur in the current corpus but are legal. New-MockKey -Name "$root\EdgeCases" -Values @{ 'Path With Backslash' = @{ Kind = 'String'; Data = 'C:\Program Files\GE' } 'Has "Quotes"' = @{ Kind = 'String'; Data = 'say "hi"' } 'Empty' = @{ Kind = 'String'; Data = '' } 'Expanded' = @{ Kind = 'ExpandString'; Data = '%SystemRoot%\dnc' } 'Multi' = @{ Kind = 'MultiString'; Data = @('one','two') } 'Blob' = @{ Kind = 'Binary'; Data = [byte[]](1,2,255) } 'Big' = @{ Kind = 'QWord'; Data = [uint64]1234567890123 } } ) $text = Export-DncToReg -Keys $keys # UTF-16LE + BOM, matching what the real script posts. $bytes = [byte[]](0xFF, 0xFE) + [Text.Encoding]::Unicode.GetBytes($text) [IO.File]::WriteAllBytes($OutFile, $bytes) Write-Host "Wrote $OutFile ($($bytes.Length) bytes)" Write-Host '--- first lines ---' ($text -split "`r`n" | Select-Object -First 12) | ForEach-Object { Write-Host " $_" }