Wax/Trace triad: arrow-key bay picker + S: backup path
Two operator-UX improvements for the Backup / Export / Install triad. 1. Backup target moves from \\tsgwp00525\...\formtracepac to S:\2 WJ Scans Record Retention\backup\waxtrace\<asset>\. S: is mapped at shopfloor imaging time and stays mapped post-categorization, so the same default path works whether the operator runs the backup on an old bay (manual pre-image capture) or a freshly imaged one. The destination directory is created if missing. 2. New Select-WaxtraceAsset.ps1 - arrow-key bay picker patterned after the WinPE select-waxtrace-asset.ps1. Reads bay-config.csv (sibling file), shows asset_tag + ftpak_version + model + user_id per row, and returns the selected asset_tag via stdout. Falls back to a manual entry prompt if the CSV is missing or the operator picks "Other". Backup / Export / Install now invoke the picker when interactive AND bay-config.csv is alongside the script. Non-interactive paths (qga / SYSTEM / scheduled task) keep silently defaulting to COMPUTERNAME so unattended runs are unchanged. Export gained an -AssetNumber parameter and stamps it into the output CSV filename so multiple inventories from the same host stay distinguishable when the operator is auditing several bays in a row. bay-config.csv is copied into the scripts\ dir so the picker has a source of truth that ships next to the scripts (and into pxe-images for tech distribution). Smoke tested on win11 VM: all four PS1 parse-clean, non-interactive backup path still produces a valid ZIP (silent COMPUTERNAME default), picker handles missing-CSV gracefully (manual-entry fallback). The arrow-key UX itself is operator-verifiable only on a real terminal.
This commit is contained in:
@@ -16,13 +16,13 @@
|
||||
Asset number (e.g. WJRP1234) used to namespace the backup on the shopfloor
|
||||
share. If omitted, the script prompts interactively and defaults to the
|
||||
current $env:COMPUTERNAME. The asset number is the leaf folder under
|
||||
\\tsgwp00525.wjs.geaerospace.net\shared\DT\Shopfloor\backup\formtracepac\
|
||||
S:\2 WJ Scans Record Retention\backup\waxtrace\
|
||||
Ignored if -Destination is supplied.
|
||||
|
||||
.PARAMETER Destination
|
||||
Where to write the ZIP file. Can be a USB drive, network share, or local path.
|
||||
If omitted, defaults to the per-asset path on the GE shopfloor share:
|
||||
\\tsgwp00525.wjs.geaerospace.net\shared\DT\Shopfloor\backup\formtracepac\<AssetNumber>
|
||||
If omitted, defaults to the per-asset path on the mapped S: drive:
|
||||
S:\2 WJ Scans Record Retention\backup\waxtrace\<AssetNumber>
|
||||
The destination directory is created if it does not exist.
|
||||
|
||||
.PARAMETER NoZip
|
||||
@@ -45,18 +45,31 @@ param(
|
||||
[switch]$IncludeExecutables
|
||||
)
|
||||
|
||||
$SharedRoot = '\\tsgwp00525.wjs.geaerospace.net\shared\DT\Shopfloor\backup\formtracepac'
|
||||
$SharedRoot = 'S:\2 WJ Scans Record Retention\backup\waxtrace'
|
||||
|
||||
if (-not $Destination) {
|
||||
if (-not $AssetNumber) {
|
||||
$defaultAsset = $env:COMPUTERNAME
|
||||
if ([Environment]::UserInteractive -and -not [Console]::IsInputRedirected) {
|
||||
# Prefer arrow-key picker against bay-config.csv if it is sitting
|
||||
# next to this script. Falls through to a plain Read-Host prompt
|
||||
# if no picker / no CSV available.
|
||||
$picker = Join-Path $PSScriptRoot 'Select-WaxtraceAsset.ps1'
|
||||
$cfg = Join-Path $PSScriptRoot 'bay-config.csv'
|
||||
if ((Test-Path -LiteralPath $picker) -and (Test-Path -LiteralPath $cfg)) {
|
||||
$picked = & $picker -ConfigCsv $cfg -Title 'Backup FormTracePak - pick the bay being captured'
|
||||
if ($picked) {
|
||||
$AssetNumber = $picked
|
||||
}
|
||||
}
|
||||
if (-not $AssetNumber) {
|
||||
$input = Read-Host "Asset number for this backup (e.g. WJRP1234) [$defaultAsset]"
|
||||
if ([string]::IsNullOrWhiteSpace($input)) {
|
||||
$AssetNumber = $defaultAsset
|
||||
} else {
|
||||
$AssetNumber = $input.Trim()
|
||||
}
|
||||
}
|
||||
} else {
|
||||
# Non-interactive (qga / SYSTEM / scheduled task): fall back to COMPUTERNAME silently.
|
||||
$AssetNumber = $defaultAsset
|
||||
|
||||
@@ -15,16 +15,46 @@
|
||||
.PARAMETER ComputerName
|
||||
Hostname to stamp on the inventory rows. Defaults to $env:COMPUTERNAME.
|
||||
|
||||
.PARAMETER AssetNumber
|
||||
Asset number (e.g. WJRP1234) used in the output CSV filename so multiple
|
||||
inventories from the same host stay distinguishable. If omitted, the script
|
||||
prompts interactively (with arrow-key picker if bay-config.csv is alongside)
|
||||
and defaults to $ComputerName non-interactively.
|
||||
|
||||
.EXAMPLE
|
||||
.\Export-FormtracepakInventory.ps1
|
||||
.\Export-FormtracepakInventory.ps1 -OutputPath "E:\inventories"
|
||||
.\Export-FormtracepakInventory.ps1 -OutputPath "E:\inventories" -AssetNumber WJRP2335
|
||||
#>
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[string]$OutputPath = $PSScriptRoot,
|
||||
[string]$ComputerName = $env:COMPUTERNAME
|
||||
[string]$ComputerName = $env:COMPUTERNAME,
|
||||
[string]$AssetNumber
|
||||
)
|
||||
|
||||
if (-not $AssetNumber) {
|
||||
if ([Environment]::UserInteractive -and -not [Console]::IsInputRedirected) {
|
||||
$picker = Join-Path $PSScriptRoot 'Select-WaxtraceAsset.ps1'
|
||||
$cfg = Join-Path $PSScriptRoot 'bay-config.csv'
|
||||
if ((Test-Path -LiteralPath $picker) -and (Test-Path -LiteralPath $cfg)) {
|
||||
$picked = & $picker -ConfigCsv $cfg -Title 'Inventory FormTracePak - pick the bay being audited'
|
||||
if ($picked) {
|
||||
$AssetNumber = $picked
|
||||
}
|
||||
}
|
||||
if (-not $AssetNumber) {
|
||||
$assetInput = Read-Host "Asset number to stamp on inventory (e.g. WJRP1234) [$ComputerName]"
|
||||
if ([string]::IsNullOrWhiteSpace($assetInput)) {
|
||||
$AssetNumber = $ComputerName
|
||||
} else {
|
||||
$AssetNumber = $assetInput.Trim()
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$AssetNumber = $ComputerName
|
||||
}
|
||||
}
|
||||
|
||||
Set-StrictMode -Version Latest
|
||||
$ErrorActionPreference = 'Continue'
|
||||
|
||||
@@ -98,7 +128,7 @@ $MitutoyoFileExtensions = @(
|
||||
# ----------------------------------------------------------------------
|
||||
|
||||
$timestamp = Get-Date -Format 'yyyyMMdd_HHmmss'
|
||||
$csvFile = Join-Path $OutputPath "formtracepak_inventory_${ComputerName}_${timestamp}.csv"
|
||||
$csvFile = Join-Path $OutputPath "formtracepak_inventory_${AssetNumber}_${ComputerName}_${timestamp}.csv"
|
||||
$inventory = [System.Collections.Generic.List[PSObject]]::new()
|
||||
|
||||
function Add-Item {
|
||||
|
||||
@@ -20,8 +20,8 @@
|
||||
.PARAMETER BackupPath
|
||||
Path to the backup ZIP, directory containing a backup ZIP, or already-extracted
|
||||
backup folder created by Backup-FormtracepakSettings.ps1. If omitted, defaults
|
||||
to the per-asset path on the GE shopfloor share:
|
||||
\\tsgwp00525.wjs.geaerospace.net\shared\DT\Shopfloor\backup\formtracepac\<AssetNumber>
|
||||
to the per-asset path on the mapped S: drive:
|
||||
S:\2 WJ Scans Record Retention\backup\waxtrace\<AssetNumber>
|
||||
If the path is a directory, the newest formtracepak_backup_*.zip inside it is used.
|
||||
|
||||
.PARAMETER RestoreRegistry
|
||||
@@ -60,18 +60,29 @@ param(
|
||||
[switch]$Force
|
||||
)
|
||||
|
||||
$SharedRoot = '\\tsgwp00525.wjs.geaerospace.net\shared\DT\Shopfloor\backup\formtracepac'
|
||||
$SharedRoot = 'S:\2 WJ Scans Record Retention\backup\waxtrace'
|
||||
|
||||
if (-not $BackupPath) {
|
||||
if (-not $AssetNumber) {
|
||||
$defaultAsset = $env:COMPUTERNAME
|
||||
if ([Environment]::UserInteractive -and -not [Console]::IsInputRedirected) {
|
||||
# Prefer arrow-key picker against bay-config.csv if available.
|
||||
$picker = Join-Path $PSScriptRoot 'Select-WaxtraceAsset.ps1'
|
||||
$cfg = Join-Path $PSScriptRoot 'bay-config.csv'
|
||||
if ((Test-Path -LiteralPath $picker) -and (Test-Path -LiteralPath $cfg)) {
|
||||
$picked = & $picker -ConfigCsv $cfg -Title 'Restore FormTracePak - pick the bay being restored'
|
||||
if ($picked) {
|
||||
$AssetNumber = $picked
|
||||
}
|
||||
}
|
||||
if (-not $AssetNumber) {
|
||||
$assetInput = Read-Host "Asset number to restore (e.g. WJRP1234) [$defaultAsset]"
|
||||
if ([string]::IsNullOrWhiteSpace($assetInput)) {
|
||||
$AssetNumber = $defaultAsset
|
||||
} else {
|
||||
$AssetNumber = $assetInput.Trim()
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$AssetNumber = $defaultAsset
|
||||
Write-Host "Non-interactive session - defaulting AssetNumber to $AssetNumber. Pass -AssetNumber or -BackupPath to override."
|
||||
|
||||
@@ -0,0 +1,110 @@
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Arrow-key bay picker for Wax/Trace Export / Backup / Install scripts.
|
||||
|
||||
.DESCRIPTION
|
||||
Reads bay-config.csv (asset_tag,ftpak_version,model,user_id) and presents
|
||||
an Up/Down picker. Returns the chosen asset_tag to stdout so the calling
|
||||
script can capture it. Always appends an "Other (manual entry)" option.
|
||||
|
||||
Same UX as the WinPE select-waxtrace-asset.ps1 used by startnet.cmd.
|
||||
Distinct from that script because it returns the asset tag via stdout
|
||||
rather than writing to a file, and presents the richer per-bay columns
|
||||
(FTPak version + model + USER ID) from bay-config.csv.
|
||||
|
||||
.PARAMETER ConfigCsv
|
||||
Path to bay-config.csv. Defaults to a sibling file next to this script.
|
||||
|
||||
.PARAMETER Title
|
||||
Header text shown above the picker. Defaults to "Wax/Trace Asset".
|
||||
|
||||
.OUTPUTS
|
||||
String. The chosen asset_tag, printed to stdout. Empty string on cancel.
|
||||
|
||||
.EXAMPLE
|
||||
$asset = & .\Select-WaxtraceAsset.ps1
|
||||
$asset = & .\Select-WaxtraceAsset.ps1 -ConfigCsv 'C:\foo\bay-config.csv' -Title 'Pick bay to back up'
|
||||
#>
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[string]$ConfigCsv = (Join-Path $PSScriptRoot 'bay-config.csv'),
|
||||
[string]$Title = 'Wax/Trace Asset'
|
||||
)
|
||||
|
||||
$ErrorActionPreference = 'Continue'
|
||||
|
||||
function Read-BayList {
|
||||
param([string]$Path)
|
||||
if (-not (Test-Path -LiteralPath $Path)) { return @() }
|
||||
try {
|
||||
return Import-Csv -LiteralPath $Path |
|
||||
Sort-Object -Property asset_tag
|
||||
} catch {
|
||||
return @()
|
||||
}
|
||||
}
|
||||
|
||||
function Show-Menu {
|
||||
param([object[]]$Items, [int]$Selected, [string]$Title)
|
||||
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 ''
|
||||
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 '-----', '-----', '-----', '-------')
|
||||
for ($i = 0; $i -lt $Items.Count; $i++) {
|
||||
$item = $Items[$i]
|
||||
if ($item -is [string]) {
|
||||
$line = $item
|
||||
} else {
|
||||
$line = '{0,-10} {1,-8} {2,-10} {3}' -f $item.asset_tag, $item.ftpak_version, $item.model, $item.user_id
|
||||
}
|
||||
if ($i -eq $Selected) {
|
||||
Write-Host (' > ' + $line) -ForegroundColor Black -BackgroundColor White
|
||||
} else {
|
||||
Write-Host (' ' + $line)
|
||||
}
|
||||
}
|
||||
Write-Host ''
|
||||
}
|
||||
|
||||
$bays = @(Read-BayList -Path $ConfigCsv)
|
||||
$menuItems = @()
|
||||
foreach ($b in $bays) { $menuItems += $b }
|
||||
$menuItems += '** Other (enter asset tag manually) **'
|
||||
|
||||
if ($menuItems.Count -eq 1) {
|
||||
# Only the manual-entry sentinel: CSV missing or unparseable. Fall back
|
||||
# to a plain prompt rather than wedging the operator in an empty menu.
|
||||
Write-Host " (bay-config.csv not readable at $ConfigCsv - falling back to manual entry)"
|
||||
$manual = Read-Host " Enter asset tag (e.g. WJRP9999) or blank to abort"
|
||||
if ($manual) { return $manual.Trim().ToUpper() } else { return '' }
|
||||
}
|
||||
|
||||
$sel = 0
|
||||
while ($true) {
|
||||
Show-Menu -Items $menuItems -Selected $sel -Title $Title
|
||||
$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) {
|
||||
return $manual.Trim().ToUpper()
|
||||
} else {
|
||||
return ''
|
||||
}
|
||||
} else {
|
||||
return $bays[$sel].asset_tag
|
||||
}
|
||||
}
|
||||
'Escape' { return '' }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
asset_tag,ftpak_version,model,user_id
|
||||
WJF00159,6.103,AVANT,3974839712
|
||||
WJRP3689,5.510,CV-4500,3744284509
|
||||
WJRP2660,6.0,CV-4500,2365986521
|
||||
WJRP2659,6.0,CV-4500,2709054503
|
||||
WJF00545,6.213,AVANT,3878777362
|
||||
WJRP3638,5.602,CV-4500,0720778210
|
||||
WJF00052,6.103,AVANT,3270314998
|
||||
WJF00084,6.103,AVANT,1476212857
|
||||
WJF00083,6.103,AVANT,2934506987
|
||||
WJRP3025,6.0,CV-3200,2292822471
|
||||
WJF00197,6.104,AVANT,1191612605
|
||||
WJRP4802,6.002,AVANT,0920866935
|
||||
WJRP2347,6.0,CV-4500,3585172946
|
||||
WJRP2035,6.0,CV-4500,2292822471
|
||||
WJRP2335,6.0,CV-4500,1780916688
|
||||
|
Reference in New Issue
Block a user