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>
This commit is contained in:
10
playbook/utilities/waxtrace-recovery/debug-waxtrace-cal.bat
Normal file
10
playbook/utilities/waxtrace-recovery/debug-waxtrace-cal.bat
Normal file
@@ -0,0 +1,10 @@
|
||||
@echo off
|
||||
REM Right-click "Run as administrator". Forwards args to debug-waxtrace-cal.ps1.
|
||||
REM Optional: debug-waxtrace-cal.bat -Asset WJF00159 (overrides machine-number.txt).
|
||||
REM Output: C:\Logs\WaxTrace\debug-waxtrace-cal.log
|
||||
powershell.exe -NoProfile -ExecutionPolicy Bypass -File "%~dp0debug-waxtrace-cal.ps1" %*
|
||||
echo.
|
||||
echo Done. Full log: C:\Logs\WaxTrace\debug-waxtrace-cal.log
|
||||
echo.
|
||||
pause
|
||||
exit /b %ERRORLEVEL%
|
||||
272
playbook/utilities/waxtrace-recovery/debug-waxtrace-cal.ps1
Normal file
272
playbook/utilities/waxtrace-recovery/debug-waxtrace-cal.ps1
Normal file
@@ -0,0 +1,272 @@
|
||||
# debug-waxtrace-cal.ps1 - Forensic walkthrough of why the wax/trace
|
||||
# calibration data did not land in FormTracePak's data dir on a bay.
|
||||
#
|
||||
# Captures everything: FTPak install location autodetected (we DO NOT
|
||||
# trust the hardcoded path), data dir contents at every candidate,
|
||||
# cal ISO presence + mount + listing, the current on-disk version of
|
||||
# 09-Setup-WaxAndTrace.ps1 (does it have the direct-copy fix or the old
|
||||
# vendor-Setup.exe path?), the imaging-time log, and Application event
|
||||
# log entries for Setup.exe crashes in the last 24 hours.
|
||||
#
|
||||
# Run as administrator. Output to C:\Logs\WaxTrace\debug-waxtrace-cal.log
|
||||
# + console. Paste the log back to support for diagnosis.
|
||||
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[string]$Asset
|
||||
)
|
||||
|
||||
$logDir = 'C:\Logs\WaxTrace'
|
||||
if (-not (Test-Path $logDir)) { New-Item -ItemType Directory -Path $logDir -Force | Out-Null }
|
||||
$logFile = Join-Path $logDir 'debug-waxtrace-cal.log'
|
||||
Remove-Item $logFile -Force -EA 0
|
||||
|
||||
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 '=== debug-waxtrace-cal.ps1 ==='
|
||||
Log "User: $([Security.Principal.WindowsIdentity]::GetCurrent().Name)"
|
||||
Log "Host: $env:COMPUTERNAME"
|
||||
|
||||
# ---------- Section 1: Asset tag ----------
|
||||
Log ''
|
||||
Log '--- 1. ASSET TAG ---'
|
||||
if (-not $Asset) {
|
||||
$mn = 'C:\Enrollment\machine-number.txt'
|
||||
if (Test-Path $mn) {
|
||||
$Asset = (Get-Content $mn -First 1 -EA 0).Trim()
|
||||
Log "machine-number.txt: '$Asset'"
|
||||
} else {
|
||||
Log "machine-number.txt MISSING at $mn" 'WARN'
|
||||
}
|
||||
}
|
||||
Log "Using asset: $Asset"
|
||||
|
||||
# ---------- Section 2: locate FormTracePak install ----------
|
||||
Log ''
|
||||
Log '--- 2. FORMTRACEPAK INSTALL LOCATION ---'
|
||||
$candidatePaths = @(
|
||||
'C:\Program Files (x86)\MitutoyoApp\Formtracepak',
|
||||
'C:\Program Files\MitutoyoApp\Formtracepak',
|
||||
'C:\Program Files (x86)\Mitutoyo\Formtracepak',
|
||||
'C:\Program Files\Mitutoyo\Formtracepak',
|
||||
'C:\MitutoyoApp\Formtracepak',
|
||||
'C:\Mitutoyo\Formtracepak'
|
||||
)
|
||||
$ftpakRoot = $null
|
||||
foreach ($p in $candidatePaths) {
|
||||
$exe = Join-Path $p 'Formtracepak.exe'
|
||||
if (Test-Path -LiteralPath $exe) {
|
||||
$ftpakRoot = $p
|
||||
Log "FOUND Formtracepak.exe at: $exe"
|
||||
break
|
||||
} else {
|
||||
Log " miss: $p"
|
||||
}
|
||||
}
|
||||
|
||||
if (-not $ftpakRoot) {
|
||||
Log 'No Formtracepak.exe at any expected path - searching C:\ Program Files trees...'
|
||||
$hits = @()
|
||||
foreach ($pf in @('C:\Program Files', 'C:\Program Files (x86)', 'C:\Mitutoyo', 'C:\MitutoyoApp')) {
|
||||
if (-not (Test-Path $pf)) { continue }
|
||||
$hits += Get-ChildItem -Path $pf -Filter 'Formtracepak.exe' -Recurse -File -ErrorAction SilentlyContinue
|
||||
}
|
||||
if ($hits) {
|
||||
Log "Brute-force search hits:"
|
||||
$hits | ForEach-Object { Log " $($_.FullName)" }
|
||||
$ftpakRoot = Split-Path $hits[0].FullName -Parent
|
||||
} else {
|
||||
Log 'NO Formtracepak.exe ANYWHERE on C:\ - FormTracePak install likely never completed.' 'ERROR'
|
||||
}
|
||||
}
|
||||
|
||||
# ---------- Section 3: data dir + contents ----------
|
||||
Log ''
|
||||
Log '--- 3. FORMTRACEPAK DATA DIR ---'
|
||||
if ($ftpakRoot) {
|
||||
$dataDir = Join-Path $ftpakRoot 'data'
|
||||
Log "Expected data dir: $dataDir"
|
||||
if (Test-Path -LiteralPath $dataDir) {
|
||||
$files = Get-ChildItem -LiteralPath $dataDir -File -EA 0 | Sort-Object Name
|
||||
if ($files) {
|
||||
Log "Data dir contents ($($files.Count) files):"
|
||||
foreach ($f in $files) {
|
||||
Log " $($f.Name) ($($f.Length) bytes, modified $($f.LastWriteTime))"
|
||||
}
|
||||
} else {
|
||||
Log 'Data dir EXISTS but is EMPTY' 'WARN'
|
||||
}
|
||||
# Look for any cal files matching the asset's probe ID
|
||||
$probeMatches = $files | Where-Object { $_.Name -match '218-\d{3}-\d+' }
|
||||
if ($probeMatches) {
|
||||
Log 'Files with probe-ID pattern (cal data candidates):'
|
||||
foreach ($f in $probeMatches) { Log " hit: $($f.Name)" }
|
||||
} else {
|
||||
Log 'NO files matching the 218-XXX-XX probe-ID pattern in data dir.' 'WARN'
|
||||
}
|
||||
} else {
|
||||
Log "Data dir MISSING at $dataDir" 'ERROR'
|
||||
Log "Parent dir contents:"
|
||||
Get-ChildItem -LiteralPath $ftpakRoot -EA 0 | ForEach-Object { Log " $($_.Name)" }
|
||||
}
|
||||
} else {
|
||||
Log 'Skipping data-dir check (FTPak install not found)'
|
||||
}
|
||||
|
||||
# ---------- Section 4: cal ISO present at C:\WaxTrace-Install\calibrations\ ----------
|
||||
Log ''
|
||||
Log '--- 4. CAL ISO ON LOCAL DISK ---'
|
||||
$calDir = 'C:\WaxTrace-Install\calibrations'
|
||||
if (Test-Path -LiteralPath $calDir) {
|
||||
$allCals = Get-ChildItem -LiteralPath $calDir -Filter 'CAL-*.iso' -File -EA 0
|
||||
Log "Cal staging dir: $calDir ($($allCals.Count) ISO files total)"
|
||||
if ($Asset) {
|
||||
$matched = $allCals | Where-Object { $_.Name -like "CAL-${Asset}_*" }
|
||||
if ($matched) {
|
||||
Log "ISO matching this asset:"
|
||||
foreach ($f in $matched) { Log " $($f.Name) ($([math]::Round($f.Length/1KB,1)) KB)" }
|
||||
} else {
|
||||
Log "NO ISO matches CAL-${Asset}_*.iso in $calDir" 'ERROR'
|
||||
Log "Available ISOs (first 8):"
|
||||
$allCals | Select-Object -First 8 | ForEach-Object { Log " $($_.Name)" }
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Log "Cal staging dir MISSING: $calDir - startnet.cmd did not xcopy installers-post\waxtrace at imaging time, OR 09-Setup-WaxAndTrace.ps1 already deleted it (Step 5 cleanup)." 'ERROR'
|
||||
}
|
||||
|
||||
# ---------- Section 5: mount the matching cal ISO and list contents ----------
|
||||
Log ''
|
||||
Log '--- 5. MOUNT CAL ISO + LIST CONTENTS ---'
|
||||
if ($Asset -and (Test-Path -LiteralPath $calDir)) {
|
||||
$iso = Get-ChildItem -LiteralPath $calDir -Filter "CAL-${Asset}_*.iso" -EA 0 | Select-Object -First 1
|
||||
if ($iso) {
|
||||
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 ($drive) {
|
||||
Log "Mounted at ${drive}:\ (label=$($vol.FileSystemLabel))"
|
||||
$items = [System.IO.Directory]::GetFileSystemEntries("${drive}:\", '*', 'AllDirectories')
|
||||
foreach ($i in $items) {
|
||||
try {
|
||||
$fi = [System.IO.FileInfo]::new($i)
|
||||
if ($fi.Attributes -band [System.IO.FileAttributes]::Directory) {
|
||||
Log " DIR $i"
|
||||
} else {
|
||||
Log " FILE $i ($($fi.Length) bytes)"
|
||||
}
|
||||
} catch { Log " $i" }
|
||||
}
|
||||
} else {
|
||||
Log "Mount succeeded but no drive letter assigned" 'ERROR'
|
||||
}
|
||||
Dismount-DiskImage -ImagePath $iso.FullName -EA 0 | Out-Null
|
||||
Log "Cal ISO dismounted"
|
||||
} catch {
|
||||
Log "Mount failed: $_" 'ERROR'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# ---------- Section 6: on-disk version of 09-Setup-WaxAndTrace.ps1 ----------
|
||||
Log ''
|
||||
Log '--- 6. 09-SETUP-WAXANDTRACE.PS1 ON DISK ---'
|
||||
$setupPath = 'C:\Enrollment\shopfloor-setup\gea-shopfloor-waxtrace\09-Setup-WaxAndTrace.ps1'
|
||||
if (Test-Path -LiteralPath $setupPath) {
|
||||
$fi = Get-Item $setupPath
|
||||
Log "Path: $setupPath"
|
||||
Log " size: $($fi.Length) bytes, mtime: $($fi.LastWriteTime)"
|
||||
$content = Get-Content -LiteralPath $setupPath -Raw
|
||||
$hasDirectCopy = $content -match 'hasBrokenFilenames'
|
||||
$hasV6213 = $content -match 'V6\.213'
|
||||
$vendorOnly = $content -match 'calSetup.*Setup\.exe' -and -not $hasDirectCopy
|
||||
Log " Direct-copy bypass present (hasBrokenFilenames): $hasDirectCopy"
|
||||
Log " V6.213 baseline references: $hasV6213"
|
||||
if (-not $hasDirectCopy) {
|
||||
Log ' !!! This bay has the OLD 09-Setup-WaxAndTrace.ps1 without the direct-copy fix.' 'ERROR'
|
||||
Log ' !!! 218-378-13 series cal discs WILL crash setup.exe with .NET unhandled exception.' 'ERROR'
|
||||
Log ' !!! Pull the latest from the share: copy /Y \\172.16.9.1\enrollment\shopfloor-setup\gea-shopfloor-waxtrace\09-Setup-WaxAndTrace.ps1 to local.' 'ERROR'
|
||||
}
|
||||
} else {
|
||||
Log "09-Setup-WaxAndTrace.ps1 NOT FOUND at expected path $setupPath" 'WARN'
|
||||
}
|
||||
|
||||
# Also check C:\WaxTrace-Install copy (staged from share at WinPE time)
|
||||
$setupStaging = 'C:\WaxTrace-Install\09-Setup-WaxAndTrace.ps1'
|
||||
if (Test-Path -LiteralPath $setupStaging) {
|
||||
$fi = Get-Item $setupStaging
|
||||
$content = Get-Content -LiteralPath $setupStaging -Raw
|
||||
$hasDirectCopy = $content -match 'hasBrokenFilenames'
|
||||
Log "Staging copy at $setupStaging :"
|
||||
Log " size: $($fi.Length), mtime: $($fi.LastWriteTime), has direct-copy: $hasDirectCopy"
|
||||
}
|
||||
|
||||
# ---------- Section 7: imaging-time log content ----------
|
||||
Log ''
|
||||
Log '--- 7. 09-SETUP-WAXANDTRACE.LOG CONTENT (cal sections) ---'
|
||||
$wtLog = 'C:\Logs\WaxTrace\09-Setup-WaxAndTrace.log'
|
||||
if (Test-Path -LiteralPath $wtLog) {
|
||||
Log "Tail of $wtLog (last 40 lines + cal-related lines):"
|
||||
$tail = Get-Content -LiteralPath $wtLog -Tail 40 -EA 0
|
||||
foreach ($l in $tail) { Log " $l" }
|
||||
Log ''
|
||||
Log 'cal/calibration/setup/copy/Mount-DiskImage matching lines:'
|
||||
Select-String -LiteralPath $wtLog -Pattern 'cal|calibration|copied|direct copy|Mount-DiskImage|setup\.exe exit|hasBrokenFilenames' -SimpleMatch:$false -EA 0 |
|
||||
Select-Object -Last 30 | ForEach-Object { Log " L$($_.LineNumber): $($_.Line)" }
|
||||
} else {
|
||||
Log "$wtLog MISSING - 09-Setup-WaxAndTrace.ps1 never ran (or never reached transcript start)." 'WARN'
|
||||
}
|
||||
|
||||
# ---------- Section 8: Event log .NET Runtime crashes ----------
|
||||
Log ''
|
||||
Log '--- 8. EVENT LOG (.NET Runtime / Application Error / WER, last 24h) ---'
|
||||
$cutoff = (Get-Date).AddHours(-24)
|
||||
foreach ($lname in @('Application')) {
|
||||
try {
|
||||
$events = Get-WinEvent -FilterHashtable @{
|
||||
LogName = $lname
|
||||
StartTime = $cutoff
|
||||
ProviderName = @('.NET Runtime', 'Application Error', 'Windows Error Reporting')
|
||||
} -ErrorAction Stop | Where-Object { $_.Message -match 'setup\.exe|Setup\.exe|MitutoyoLauncher|Formtracepak|FileSystemInfo|set_Attributes' } |
|
||||
Select-Object -First 5
|
||||
if ($events) {
|
||||
foreach ($e in $events) {
|
||||
Log "Event $($e.Id) [$($e.LevelDisplayName)] from $($e.ProviderName) at $($e.TimeCreated)"
|
||||
$e.Message -split "`n" | Select-Object -First 10 | ForEach-Object { Log " $_" }
|
||||
}
|
||||
} else {
|
||||
Log "No matching .NET/AppError events in last 24h"
|
||||
}
|
||||
} catch {}
|
||||
}
|
||||
|
||||
# ---------- Section 9: scoped search for cal data on known dirs ----------
|
||||
Log ''
|
||||
Log '--- 9. SCOPED CAL FILE SEARCH (Mitutoyo / Hexagon known dirs) ---'
|
||||
$searchRoots = @(
|
||||
'C:\Program Files (x86)\MitutoyoApp',
|
||||
'C:\Program Files\MitutoyoApp',
|
||||
'C:\Program Files (x86)\Mitutoyo',
|
||||
'C:\Program Files\Mitutoyo',
|
||||
'C:\MitutoyoApp',
|
||||
'C:\Mitutoyo',
|
||||
'C:\ProgramData\Mitutoyo'
|
||||
)
|
||||
foreach ($r in $searchRoots) {
|
||||
if (-not (Test-Path -LiteralPath $r)) { continue }
|
||||
$hits = @(Get-ChildItem -Path $r -Include 'Frc_*.txt','Linear_X_*.txt','Linear_Zl_*.txt','Str_XZ_*.txt','cvifdll.ini','CVIFDLL.ini' -Recurse -ErrorAction SilentlyContinue -Force)
|
||||
if ($hits) {
|
||||
Log "Under $r :"
|
||||
$hits | Select-Object -First 10 | ForEach-Object { Log " $($_.FullName) ($($_.Length) bytes, $($_.LastWriteTime))" }
|
||||
}
|
||||
}
|
||||
|
||||
Log ''
|
||||
Log "=== debug-waxtrace-cal.ps1 end. Output: $logFile ==="
|
||||
12
playbook/utilities/waxtrace-recovery/fix-waxtrace-cal.bat
Normal file
12
playbook/utilities/waxtrace-recovery/fix-waxtrace-cal.bat
Normal file
@@ -0,0 +1,12 @@
|
||||
@echo off
|
||||
REM fix-waxtrace-cal.bat - Double-click launcher for fix-waxtrace-cal.ps1.
|
||||
REM Right-click "Run as administrator" so files can land under Program Files.
|
||||
REM Forwards args, e.g.:
|
||||
REM fix-waxtrace-cal.bat -Asset WJF00159
|
||||
REM If no -Asset is passed the script reads C:\Enrollment\machine-number.txt.
|
||||
powershell.exe -NoProfile -ExecutionPolicy Bypass -File "%~dp0fix-waxtrace-cal.ps1" %*
|
||||
echo.
|
||||
echo Done. Full log: C:\Logs\WaxTrace\fix-waxtrace-cal.log
|
||||
echo.
|
||||
pause
|
||||
exit /b %ERRORLEVEL%
|
||||
175
playbook/utilities/waxtrace-recovery/fix-waxtrace-cal.ps1
Normal file
175
playbook/utilities/waxtrace-recovery/fix-waxtrace-cal.ps1
Normal file
@@ -0,0 +1,175 @@
|
||||
# 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
|
||||
Reference in New Issue
Block a user