CMM: add goCMM settings backup/restore + debug scripts

goCMM settings live in two places: 3 pointer values at
HKLM\SOFTWARE\WOW6432Node\General Electric\goCMM, and the real content of all
7 Settings tabs (PC-DMIS, Quindos, Modus, Machine Definition, User Input,
Notifications, Part Groups) in C:\geaofi\ApplicationSettings.xml. Capture-replay
pair, mirroring the Wax/Trace Backup/Install scripts:

- Backup-goCMMSettings.ps1/.bat: on a live legacy bay (admin), zips the registry
  key + the C:\geaofi tree (minus transient LocalProgramCopies/logs) to
  gocmm_backup_<PC>_<ts>.zip.
- Install-goCMMSettings.ps1/.bat: restore at imaging (admin). Imports the key +
  lays down C:\geaofi, then grants BUILTIN\Users WriteKey on the reg key and
  Modify on C:\geaofi - goCMM's RegistrySettings.GetRegistryString opens the key
  with writable:true even to READ, so a locked-down operator throws a
  SecurityException without the grant (the post-lockdown 'registry access not
  allowed' error). Applies a built-in legacy->new FQDN rewrite
  (rd.ds.ge.com -> wjs.geaerospace.net) automatically across the registry values
  and ApplicationSettings.xml (incl PartGroup FullName); -NoDefaultRewrite skips
  it, /replace adds an extra pair, -SelectedPartGroup overrides per bay.
- gocmm-debug.ps1/.bat: run as the operator to reproduce the SecurityException
  and dump the goCMM key ACL (confirms whether lockdown stripped the grant).

All round-trip + FQDN-rewrite verified on the win11 VM. NOTE: covers goCMM only;
PC-DMIS probe calibrations / custom tip angles / machine comp are owned by
PC-DMIS (Hexagon) and not captured here. Not yet wired into 09-Setup-CMM
auto-discovery.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
cproudlock
2026-06-11 08:27:30 -04:00
parent da380fbcd7
commit bfe17fe123
6 changed files with 462 additions and 0 deletions

View File

@@ -0,0 +1,91 @@
<#
Backup-goCMMSettings.ps1
Capture a goCMM bay's COMPLETE settings into one zip. Run on a LIVE legacy
goCMM device. Mirrors Backup-FormtracepakSettings.ps1.
goCMM stores settings in two places:
1. Registry pointers: HKLM\SOFTWARE\WOW6432Node\General Electric\goCMM
Shared Data Directory, Selected Part Group, Installation Directory
2. The Shared Data Directory (default C:\geaofi\) holds ApplicationSettings.xml
= the real content of ALL 7 Settings tabs: PC-DMIS, Quindos, Modus,
Machine Definition, User Input, Notifications, Part Groups.
This zip captures both so a re-imaged bay can be restored to identical settings.
Output: C:\Logs\CMM\gocmm-backup\gocmm_backup_<PC>_<timestamp>.zip
Run as administrator (reg export of HKLM + read of the data dir).
#>
param(
[string]$OutDir = 'C:\Logs\CMM\gocmm-backup'
)
$ErrorActionPreference = 'Continue'
$ts = Get-Date -Format 'yyyyMMdd-HHmmss'
New-Item -ItemType Directory -Path $OutDir -Force -ErrorAction SilentlyContinue | Out-Null
$log = Join-Path $OutDir "gocmm-backup-$ts.log"
function Log($m){ Write-Host $m; $m | Out-File -FilePath $log -Append }
$stage = Join-Path $env:TEMP "gocmm-bk-$ts"
New-Item -ItemType Directory -Path $stage, "$stage\registry", "$stage\geaofi" -Force | Out-Null
Log "==== goCMM backup on $env:COMPUTERNAME at $(Get-Date) ===="
# --- Read the 3 registry pointers (32-bit / WOW6432Node view, as the 32-bit app sees them) ---
$sharedDir = 'C:\geaofi'; $partGroup = ''; $installDir = ''
try {
$base32 = [Microsoft.Win32.RegistryKey]::OpenBaseKey('LocalMachine','Registry32')
$k = $base32.OpenSubKey('SOFTWARE\General Electric\goCMM', $false)
if ($k) {
$sharedDir = ([string]$k.GetValue('Shared Data Directory','C:\geaofi')).TrimEnd('\')
$partGroup = [string]$k.GetValue('Selected Part Group','')
$installDir = [string]$k.GetValue('Installation Directory','')
$k.Close()
Log "Shared Data Directory = $sharedDir"
Log "Selected Part Group = $partGroup"
Log "Installation Directory= $installDir"
} else { Log "WARN: goCMM registry key not found - defaulting Shared Data Directory to $sharedDir" }
} catch { Log "WARN: reading goCMM registry failed: $($_.Exception.Message)" }
# --- Export the registry key ---
reg export 'HKLM\SOFTWARE\WOW6432Node\General Electric\goCMM' "$stage\registry\goCMM.reg" /y 2>&1 | Out-Null
if (Test-Path "$stage\registry\goCMM.reg") { Log "Exported registry key" } else { Log "WARN: registry export produced no file" }
# --- Copy the Shared Data Directory (skip transient LocalProgramCopies + logs) ---
if (Test-Path $sharedDir) {
robocopy $sharedDir "$stage\geaofi" /E /XD LocalProgramCopies logs /R:1 /W:1 /NFL /NDL /NJH /NJS | Out-Null
Log "Copied $sharedDir (excluded LocalProgramCopies, logs)"
if (Test-Path "$stage\geaofi\ApplicationSettings.xml") {
Log "ApplicationSettings.xml captured (PC-DMIS + all Settings tabs)"
} else {
Log "WARN: ApplicationSettings.xml NOT found under $sharedDir - settings tabs may be unconfigured"
}
} else {
Log "WARN: Shared Data Directory $sharedDir does not exist - only the registry key will be in this backup"
}
# --- Manifest ---
$ver = ''
if ($installDir) {
$exe = Join-Path ($installDir.TrimEnd('\')) 'goCMM.exe'
if (Test-Path $exe) { $ver = (Get-Item $exe).VersionInfo.FileVersion }
}
[pscustomobject]@{
Computer = $env:COMPUTERNAME
Timestamp = (Get-Date -Format o)
SharedDataDirectory = $sharedDir
SelectedPartGroup = $partGroup
InstallationDirectory = $installDir
goCMMVersion = $ver
} | ConvertTo-Json | Out-File "$stage\manifest.json" -Encoding ascii
# --- Zip ---
$zip = Join-Path $OutDir "gocmm_backup_${env:COMPUTERNAME}_$ts.zip"
if (Test-Path $zip) { Remove-Item $zip -Force }
Add-Type -AssemblyName System.IO.Compression.FileSystem
[System.IO.Compression.ZipFile]::CreateFromDirectory($stage, $zip)
Remove-Item $stage -Recurse -Force -ErrorAction SilentlyContinue
Log "==== DONE: $zip ===="
Write-Host ""
Write-Host "goCMM backup written:" -ForegroundColor Green
Write-Host " $zip"