private/functions/Invoke-CheckedCommand.ps1
|
function Invoke-CheckedCommandWithParams { param ( [string] $command, [hashtable] $namedParams = @{}, [object[]] $positionalArgs = @() ) $global:LASTEXITCODE = 0 $exitCode = 0 # Use call operator with splatting instead of Invoke-Expression # This avoids command injection via PowerShell metacharacters in arguments if ($namedParams -and $namedParams.Count -gt 0) { if ($positionalArgs -and $positionalArgs.Count -gt 0) { & $command @namedParams @positionalArgs } else { & $command @namedParams } } elseif ($positionalArgs -and $positionalArgs.Count -gt 0) { & $command @positionalArgs } else { & $command } $success = $? if (Test-Path VARIABLE:GLOBAL:LASTEXITCODE) { $exitCode = $GLOBAL:LASTEXITCODE; } else { if (Test-Path VARIABLE:LASTEXITCODE) { $exitCode = $LASTEXITCODE; } else { $exitCode = 0; } } if (!$success -or ($exitCode -ne 0)) { Write-Debug $("$command exited with error code " + $exitCode) Write-Debug $("params: " + $($positionalArgs -join " ")) # Extract just the command name for cleaner error message $cmdName = Split-Path -Leaf $command # Use Write-Host for clean output without stack trace Write-Host "$cmdName exited with error code $exitCode" -ForegroundColor Red # Set LASTEXITCODE so callers can check it $global:LASTEXITCODE = $exitCode } } |