Files
pxe-server/playbook/utilities/waxtrace-recovery/fix-waxtrace-cal.ps1
cproudlock 4015adeb33 utilities/waxtrace-recovery: ship cal diagnostic + repair scripts
Pair of operational tools used when a wax/trace bay's cal apply fails
(218-378-13 series cal Setup.exe crash, or any future variant). Were
living in /home/camp/pxe-images/ on the workstation; promoting to the
repo so they ship with the codebase, get version-controlled, and can
be pushed onto each PXE server's enrollment share via the standard
sync flow.

debug-waxtrace-cal.ps1 (+ .bat launcher):
- 9-section forensic walkthrough that runs on the bay as admin.
- Autodetects FormTracePak install location, dumps data/ dir contents,
  finds + mounts the per-asset cal ISO, lists its contents, checks the
  on-disk 09-Setup-WaxAndTrace.ps1 for the direct-copy bypass marker,
  greps the imaging-time log for cal lines, pulls the last 24h of
  .NET Runtime / Application Error / WER events related to Setup.exe.
- Output: C:\Logs\WaxTrace\debug-waxtrace-cal.log

fix-waxtrace-cal.ps1 (+ .bat launcher):
- Idempotent recovery: mounts the bay's cal ISO, unconditionally copies
  data\* into FormTracePak's data dir, renames any filename containing
  ' _' (space-underscore) to drop the embedded space, clears read-only,
  dismounts. Works on both 218-378-13 (broken filenames) and 218-458A
  (clean filenames) since the rename is a no-op when no space is
  present. Bypasses the buggy vendor cal Setup.exe entirely.
- Output: C:\Logs\WaxTrace\fix-waxtrace-cal.log

Both already pushed to \\172.16.9.1\enrollment\tools\ on both PXE
servers earlier today; this commit lands them in the repo as the
source of truth so future PXE server builds + ad-hoc rsyncs pick
them up automatically.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-22 14:10:23 -04:00

176 lines
6.4 KiB
PowerShell

# fix-waxtrace-cal.ps1 - Repair the wax/trace calibration apply when the
# 09-Setup-WaxAndTrace.ps1 cal step failed during imaging.
#
# Diagnoses + applies in one pass:
# 1. Reads C:\Enrollment\machine-number.txt for the asset tag (e.g.
# WJF00159) or accepts -Asset on the command line.
# 2. Finds the matching cal ISO under C:\WaxTrace-Install\calibrations\.
# 3. Mounts it. Lists contents to the log.
# 4. Auto-detects FormTracePak data dir.
# 5. Copies data\*.* into the FormTracePak data dir, renaming any
# file whose probe-ID has a trailing space (Mitutoyo 218-378-13 disc
# burn-time typo - their own .NET Setup.exe crashes on this; ours
# heals the name).
# 6. Clears read-only on each landed file.
# 7. Dismounts. Verifies cal files present on disk.
#
# Run as administrator (the destination is under Program Files (x86)).
#
# Log: C:\Logs\WaxTrace\fix-waxtrace-cal.log
[CmdletBinding()]
param(
[string]$Asset,
[string]$CalDir = 'C:\WaxTrace-Install\calibrations',
[string]$FtPakRoot = 'C:\Program Files (x86)\MitutoyoApp\Formtracepak'
)
$logDir = 'C:\Logs\WaxTrace'
if (-not (Test-Path $logDir)) { New-Item -ItemType Directory -Path $logDir -Force | Out-Null }
$logFile = Join-Path $logDir 'fix-waxtrace-cal.log'
function Log {
param([string]$Msg, [string]$Lvl = 'INFO')
$line = '[{0}] [{1}] {2}' -f (Get-Date -Format 'yyyy-MM-dd HH:mm:ss'), $Lvl, $Msg
Add-Content -Path $logFile -Value $line -ErrorAction SilentlyContinue
Write-Host $line
}
Log "=== fix-waxtrace-cal.ps1 start ==="
Log "User: $([System.Security.Principal.WindowsIdentity]::GetCurrent().Name)"
# --- Resolve asset ---
if (-not $Asset) {
$mnFile = 'C:\Enrollment\machine-number.txt'
if (Test-Path -LiteralPath $mnFile) {
$Asset = (Get-Content $mnFile -First 1).Trim()
}
}
if (-not $Asset) {
Log "No asset tag (pass -Asset or set C:\Enrollment\machine-number.txt)" 'ERROR'
exit 1
}
Log "Asset: $Asset"
# --- Verify FTPak install location exists ---
$dataDir = Join-Path $FtPakRoot 'data'
if (-not (Test-Path -LiteralPath $FtPakRoot)) {
Log "FormTracePak install root not found at $FtPakRoot" 'ERROR'
Log "Cannot apply cal data without FormTracePak. Install it first via 09-Setup-WaxAndTrace.ps1." 'ERROR'
exit 1
}
if (-not (Test-Path -LiteralPath $dataDir)) {
Log "FormTracePak data dir not found at $dataDir - creating it" 'WARN'
try { New-Item -ItemType Directory -Path $dataDir -Force | Out-Null } catch { Log "Failed to create data dir: $_" 'ERROR'; exit 1 }
}
Log "FormTracePak data dir: $dataDir"
# --- Find ISO ---
$iso = Get-ChildItem -Path $CalDir -Filter "CAL-${Asset}_*.iso" -ErrorAction SilentlyContinue | Select-Object -First 1
if (-not $iso) {
Log "No cal ISO matched CAL-${Asset}_*.iso in $CalDir" 'ERROR'
Log "Available ISOs in $CalDir :" 'INFO'
Get-ChildItem -Path $CalDir -Filter 'CAL-*.iso' -ErrorAction SilentlyContinue | ForEach-Object { Log " $($_.Name)" }
exit 1
}
Log "Cal ISO: $($iso.FullName)"
# --- Mount ---
try {
$img = Mount-DiskImage -ImagePath $iso.FullName -PassThru -ErrorAction Stop
Start-Sleep -Seconds 5
$vol = Get-DiskImage -ImagePath $iso.FullName | Get-Volume
$drive = $vol.DriveLetter
if (-not $drive) {
Log "Mount succeeded but no drive letter assigned" 'ERROR'
exit 1
}
$root = "${drive}:\"
Log "Mounted at $root (label=$($vol.FileSystemLabel))"
} catch {
Log "Mount failed: $_" 'ERROR'
exit 1
}
# --- Find source data dir on the disc ---
$srcCandidates = @(
(Join-Path $root 'data'),
(Join-Path $root 'Data'),
(Join-Path $root 'DATA')
)
$srcDataDir = $null
foreach ($p in $srcCandidates) {
if (Test-Path -LiteralPath $p) { $srcDataDir = $p; break }
}
if (-not $srcDataDir) {
Log "No data dir on cal ISO at any of: $($srcCandidates -join ', ')" 'ERROR'
Dismount-DiskImage -ImagePath $iso.FullName -ErrorAction SilentlyContinue | Out-Null
exit 1
}
Log "Source data dir on cal disc: $srcDataDir"
# --- Copy with filename heal ---
$copied = 0
$failed = 0
Get-ChildItem -LiteralPath $srcDataDir -File -ErrorAction SilentlyContinue | ForEach-Object {
# Mitutoyo 218-378-13 series discs have a probe-ID typo: filename
# contains '218-378-13 _<serial>.txt' (space before underscore). Strip
# the space so the file lands with the correct canonical name that
# FormTracePak's CVIF loader expects.
$cleanName = $_.Name -replace ' _', '_'
$dst = Join-Path $dataDir $cleanName
try {
Copy-Item -LiteralPath $_.FullName -Destination $dst -Force -ErrorAction Stop
try { (Get-Item -LiteralPath $dst).Attributes = 'Normal' } catch {}
if ($_.Name -ne $cleanName) {
Log " Copied + renamed: $($_.Name) -> $cleanName"
} else {
Log " Copied: $($_.Name)"
}
$copied++
} catch {
Log " Copy FAILED for $($_.Name): $_" 'ERROR'
$failed++
}
}
# --- Also copy cvifdll.ini if it lives at the disc root (some 218-378-13
# discs put it inside data/, older 218-458A put it in data/, but neither
# put it at root - leave this as a guard) ---
$rootIni = Join-Path $root 'cvifdll.ini'
if (Test-Path -LiteralPath $rootIni) {
try {
Copy-Item -LiteralPath $rootIni -Destination (Join-Path $dataDir 'cvifdll.ini') -Force -ErrorAction Stop
Log " Copied root-level cvifdll.ini"
$copied++
} catch { Log " cvifdll.ini copy failed: $_" 'WARN' }
}
Log "Copy summary: $copied file(s) copied, $failed failure(s)"
# --- Dismount ---
try {
Dismount-DiskImage -ImagePath $iso.FullName -ErrorAction SilentlyContinue | Out-Null
Log "Cal ISO dismounted"
} catch { Log "Dismount: $_" 'WARN' }
# --- Verify ---
Log "=== VERIFY ==="
$expectedHits = Get-ChildItem -LiteralPath $dataDir -ErrorAction SilentlyContinue |
Where-Object { $_.Name -match '_\d+\.txt$' -or $_.Name -ieq 'cvifdll.ini' } |
Select-Object Name, Length, LastWriteTime
foreach ($h in $expectedHits) {
Log " $($h.Name) ($($h.Length) bytes, modified $($h.LastWriteTime))"
}
if (-not $expectedHits) {
Log " No cal files visible in $dataDir - apply may have failed" 'WARN'
}
Log "=== fix-waxtrace-cal.ps1 end ==="
Log ""
Log "Next steps:"
Log " 1. Plug in the HASP USB dongle if not already inserted."
Log " 2. Connect the probe."
Log " 3. Launch FormTracePak (Mitutoyo Launcher) and confirm it loads probe cal data without error."
exit 0