# 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 ==="