diff --git a/playbook/shopfloor-setup/gea-shopfloor-waxtrace/scripts/Backup-FormtracepakSettings.ps1 b/playbook/shopfloor-setup/gea-shopfloor-waxtrace/scripts/Backup-FormtracepakSettings.ps1 index 7dafb9b..6cccf46 100755 --- a/playbook/shopfloor-setup/gea-shopfloor-waxtrace/scripts/Backup-FormtracepakSettings.ps1 +++ b/playbook/shopfloor-setup/gea-shopfloor-waxtrace/scripts/Backup-FormtracepakSettings.ps1 @@ -47,6 +47,13 @@ param( $SharedRoot = 'S:\2 WJ Scans Record Retention\backup\waxtrace' +# Resolve the script's own directory robustly. $PSScriptRoot can come through +# empty in some hosts (IEX / dot-source / certain remote wrappers), which +# would silently skip the picker invocation below. +$scriptDir = if ($PSScriptRoot) { $PSScriptRoot } ` + elseif ($PSCommandPath) { Split-Path -Parent $PSCommandPath } ` + else { (Get-Location).Path } + if (-not $Destination) { if (-not $AssetNumber) { $defaultAsset = $env:COMPUTERNAME @@ -54,8 +61,8 @@ if (-not $Destination) { # 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' + $picker = Join-Path $scriptDir 'Select-WaxtraceAsset.ps1' + $cfg = Join-Path $scriptDir '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) { diff --git a/playbook/shopfloor-setup/gea-shopfloor-waxtrace/scripts/Export-FormtracepakInventory.ps1 b/playbook/shopfloor-setup/gea-shopfloor-waxtrace/scripts/Export-FormtracepakInventory.ps1 index 790565c..76d39e7 100755 --- a/playbook/shopfloor-setup/gea-shopfloor-waxtrace/scripts/Export-FormtracepakInventory.ps1 +++ b/playbook/shopfloor-setup/gea-shopfloor-waxtrace/scripts/Export-FormtracepakInventory.ps1 @@ -27,15 +27,35 @@ #> [CmdletBinding()] param( - [string]$OutputPath = $PSScriptRoot, + [string]$OutputPath, [string]$ComputerName = $env:COMPUTERNAME, [string]$AssetNumber ) +# $PSScriptRoot can come through empty in some PowerShell hosts (e.g. when +# the script is invoked via IEX, dot-sourced, or run through certain remote +# wrappers). The param default = $PSScriptRoot then coerces to '' on a [string] +# parameter and Join-Path later fails with "Cannot bind argument to parameter +# 'Path' because it is an empty string". Resolve $OutputPath lazily with a +# fallback chain so the script always lands on a writable directory. +if (-not $OutputPath) { + if ($PSScriptRoot) { + $OutputPath = $PSScriptRoot + } elseif ($PSCommandPath) { + $OutputPath = Split-Path -Parent $PSCommandPath + } else { + $OutputPath = (Get-Location).Path + } +} + +$scriptDir = if ($PSScriptRoot) { $PSScriptRoot } ` + elseif ($PSCommandPath) { Split-Path -Parent $PSCommandPath } ` + else { (Get-Location).Path } + if (-not $AssetNumber) { if ([Environment]::UserInteractive -and -not [Console]::IsInputRedirected) { - $picker = Join-Path $PSScriptRoot 'Select-WaxtraceAsset.ps1' - $cfg = Join-Path $PSScriptRoot 'bay-config.csv' + $picker = Join-Path $scriptDir 'Select-WaxtraceAsset.ps1' + $cfg = Join-Path $scriptDir '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) { @@ -128,7 +148,19 @@ $MitutoyoFileExtensions = @( # ---------------------------------------------------------------------- $timestamp = Get-Date -Format 'yyyyMMdd_HHmmss' -$csvFile = Join-Path $OutputPath "formtracepak_inventory_${AssetNumber}_${ComputerName}_${timestamp}.csv" + +# Ensure $OutputPath exists / is creatable BEFORE doing the slow scan, so +# the operator does not sit through a 90k-item registry walk only to have +# the final Export-Csv fail. +if (-not (Test-Path -LiteralPath $OutputPath)) { + try { + New-Item -ItemType Directory -Path $OutputPath -Force -ErrorAction Stop | Out-Null + } catch { + Write-Error "OutputPath '$OutputPath' does not exist and cannot be created: $_" + exit 1 + } +} +$csvFile = Join-Path $OutputPath "formtracepak_inventory_${AssetNumber}_${ComputerName}_${timestamp}.csv" $inventory = [System.Collections.Generic.List[PSObject]]::new() function Add-Item { diff --git a/playbook/shopfloor-setup/gea-shopfloor-waxtrace/scripts/Install-FormtracepakSettings.ps1 b/playbook/shopfloor-setup/gea-shopfloor-waxtrace/scripts/Install-FormtracepakSettings.ps1 index f0917c5..29a745b 100755 --- a/playbook/shopfloor-setup/gea-shopfloor-waxtrace/scripts/Install-FormtracepakSettings.ps1 +++ b/playbook/shopfloor-setup/gea-shopfloor-waxtrace/scripts/Install-FormtracepakSettings.ps1 @@ -62,13 +62,20 @@ param( $SharedRoot = 'S:\2 WJ Scans Record Retention\backup\waxtrace' +# Resolve the script's own directory robustly. $PSScriptRoot can come through +# empty in some hosts (IEX / dot-source / certain remote wrappers), which +# would silently skip the picker invocation below. +$scriptDir = if ($PSScriptRoot) { $PSScriptRoot } ` + elseif ($PSCommandPath) { Split-Path -Parent $PSCommandPath } ` + else { (Get-Location).Path } + 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' + $picker = Join-Path $scriptDir 'Select-WaxtraceAsset.ps1' + $cfg = Join-Path $scriptDir '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) {