Wax/Trace triad: harden against empty $PSScriptRoot
Tech ran Export-FormtracepakInventory.ps1 from S:\DT\shopfloor\scripts\ waxandtrace\ and the picker fired correctly but Export-Csv failed with 'Cannot bind argument to parameter Path because it is an empty string'. Root cause: $OutputPath defaulted to $PSScriptRoot and $PSScriptRoot came through empty in that invocation path (suspected ISE / IEX-style host or remote wrapper). On a [string] param, $null/empty default coerces to '' and Join-Path then errors. Fix in all three triad scripts: resolve a local $scriptDir via a fallback chain ($PSScriptRoot -> $PSCommandPath -> Get-Location), and use that instead of $PSScriptRoot for sibling lookups (Select-WaxtraceAsset.ps1, bay-config.csv). Export additionally: - Drops the $OutputPath = $PSScriptRoot param default in favor of the same fallback chain. - Tests / creates $OutputPath BEFORE the 90k-item registry scan so a bad output dir surfaces immediately instead of after a long scan. Smoke tested on win11 VM: explicit -OutputPath '' now resolves to a writable directory and the CSV writes successfully.
This commit is contained in:
@@ -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) {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user