# select-waxtrace-asset.ps1 - Arrow-key bay picker for wax/trace imaging. # # Reads bay-config.csv on the PXE share to build the menu of known bays. # Falls back to INDEX.csv (cal-disc index) if bay-config.csv is missing. # Operator picks with Up/Down arrows + Enter. Always appends an # "Other (new bay)" option at the end for unlisted bays - selecting it # falls back to a free-text prompt. # # Writes the chosen asset tag to $OutFile (one line, no trailing newline). # startnet.cmd reads that file back into the MACHINENUM batch var. # # Runs in WinPE PowerShell. Win10/11 WinPE ships powershell.exe with # System.Console.ReadKey support. Tested 2026-05-18. # # Exit codes: # 0 = asset tag written to $OutFile # 1 = user cancelled (Esc) - $OutFile not written # 2 = no readable bay source AND no fallback entered param( [string]$IndexPath = 'Y:\installers-post\waxtrace\bay-config.csv', [Parameter(Mandatory=$true)][string]$OutFile ) $ErrorActionPreference = 'Continue' function Read-BayList { param([string]$Path) if (-not (Test-Path -LiteralPath $Path)) { return @() } try { $rows = @(Import-Csv -LiteralPath $Path) # bay-config.csv has asset_tag,ftpak_version,model,user_id,hw_sn,hw_id,host,notes # INDEX.csv (legacy) has asset_tag,unit_serial,probe_part,... $isBayCfg = $rows.Count -gt 0 -and ($rows[0].PSObject.Properties.Name -contains 'ftpak_version') return $rows | Sort-Object -Property asset_tag | ForEach-Object { if ($isBayCfg) { [PSCustomObject]@{ asset_tag = $_.asset_tag col1 = $_.ftpak_version col2 = $_.model col3 = $_.user_id schema = 'bay-config' } } else { [PSCustomObject]@{ asset_tag = $_.asset_tag col1 = $_.unit_serial col2 = $_.probe_part col3 = '' schema = 'index' } } } } catch { return @() } } function Show-Menu { param([object[]]$Items, [int]$Selected, [string]$Title, [string]$Schema) Clear-Host Write-Host "" Write-Host " ============================================================" Write-Host " $Title" Write-Host " ============================================================" Write-Host "" Write-Host " Up / Down arrows = navigate, Enter = select, Esc = cancel" Write-Host "" if ($Schema -eq 'bay-config') { Write-Host (" {0,-10} {1,-8} {2,-10} {3}" -f 'ASSET','FTPAK','MODEL','USER ID') Write-Host (" {0,-10} {1,-8} {2,-10} {3}" -f '-----','-----','-----','-------') } else { Write-Host (" {0,-10} {1,-14} {2}" -f 'ASSET','SERIAL','PROBE') Write-Host (" {0,-10} {1,-14} {2}" -f '-----','------','-----') } for ($i = 0; $i -lt $Items.Count; $i++) { $item = $Items[$i] if ($item -is [string]) { $line = $item } elseif ($Schema -eq 'bay-config') { $line = "{0,-10} {1,-8} {2,-10} {3}" -f $item.asset_tag, $item.col1, $item.col2, $item.col3 } else { $line = "{0,-10} {1,-14} {2}" -f $item.asset_tag, $item.col1, $item.col2 } if ($i -eq $Selected) { Write-Host (" > " + $line) -ForegroundColor Black -BackgroundColor White } else { Write-Host (" " + $line) } } Write-Host "" } # Try bay-config.csv first; fall back to INDEX.csv if missing OR if the # explicit -IndexPath argument points to INDEX.csv (legacy callers). $bays = @(Read-BayList -Path $IndexPath) if ($bays.Count -eq 0 -and $IndexPath -notmatch 'INDEX\.csv$') { $fallback = 'Y:\installers-post\waxtrace\calibrations\INDEX.csv' if (Test-Path -LiteralPath $fallback) { Write-Host " (no bay-config.csv at $IndexPath - falling back to $fallback)" $bays = @(Read-BayList -Path $fallback) } } $schema = if ($bays.Count -gt 0) { $bays[0].schema } else { 'bay-config' } $menuItems = @() foreach ($b in $bays) { $menuItems += $b } $menuItems += '** Other (new bay - enter asset tag manually) **' $sel = 0 while ($true) { Show-Menu -Items $menuItems -Selected $sel -Title 'Wax/Trace Asset Tag' -Schema $schema $key = [System.Console]::ReadKey($true) switch ($key.Key) { 'UpArrow' { if ($sel -gt 0) { $sel-- } } 'DownArrow' { if ($sel -lt ($menuItems.Count - 1)) { $sel++ } } 'Enter' { if ($sel -eq ($menuItems.Count - 1)) { Write-Host "" $manual = Read-Host " Enter asset tag (e.g. WJRP9999) or blank to abort" if ($manual) { $manual = $manual.Trim().ToUpper() Set-Content -LiteralPath $OutFile -Value $manual -NoNewline -Encoding ascii Write-Host "" Write-Host " Saved asset tag: $manual" Start-Sleep -Seconds 1 exit 0 } else { exit 1 } } else { $pick = $bays[$sel].asset_tag Set-Content -LiteralPath $OutFile -Value $pick -NoNewline -Encoding ascii Write-Host "" Write-Host " Selected: $pick" Start-Sleep -Seconds 1 exit 0 } } 'Escape' { exit 1 } } }