Problem:
I am trying to run a command via PowerShell and capture its stdout and stderr without printing them on screen (command is incredibly noisy and pollutes the console).
I want to capture the stdout and stderr in a variable and then throw an exception if particular strings are found.
My logic seems to be working and I can make the cmdlet fail/pass when I expect it to, however the output does not match what I expect, instead of returning the error message that I am specifying I get what I believe is the stderr from the command instead?
My code:
(Simplified for easier reading)
First cmdlet:
function Test-Validation
{
[CmdletBinding()]
param(
[Parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true, Position = 0)]
[Array]
$ValidExitCodes = @(0),
[Parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true, Position = 1)]
[bool]
$FailOnWarning = $true
)
$Validation = . pdk validate 2>&1
if ($LASTEXITCODE -notin $ValidExitCodes)
{
throw "Module validation has failed. Exit code: $($LASTEXITCODE)."
}
$Warnings = $Validation -match 'pdk \(WARNING\)'
if (($Warnings) -and ($FailOnWarning -eq $true))
{
throw "Module validation contains warnings.`n$Warnings"
}
Write-Verbose "Module successfully passed validation"
}
Which is called by a second cmdlet:
function Test-Module
{
[CmdletBinding()]
param
()
try
{
Test-Validation
}
catch
{
throw "$($_.Exception.Message)"
}
try
{
Test-Unit
}
catch
{
throw "$($_.Exception.Message)"
}
}
Expected output
PS /opt/script/test/> Test-Module
Exception: /opt/script/test/Test-Module.ps1:13:9
Line |
13 | throw "$($_.Exception.Message)"
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| Module validation has failed. Exit code: 1.
Actual output
PS /opt/script/test/> Test-Module
Exception: /opt/script/test/Test-Module.ps1:13:9
Line |
13 | throw "$($_.Exception.Message)"
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| pdk (INFO): Using Ruby 2.5.8
As you can see it seems to be returning the output from the command I'm running (pdk) instead of the "Module validation has failed. Exit code: $($LASTEXITCODE)."
message I am defining in the Test-Validation cmdlet.
Why am I not getting the error message I want and is there any way for me the achieve what I'm looking for? Alongside any code suggestions I would very much appreciate any further readings around my issues to so I can better understand these things.
N.B.: This is being run by PoSh Core on MacOS
pdk
, is it a native command or a PowerShell function? If it is native, then this Q&A may apply: https://mcmap.net/q/16008/-lastexitcode-0-but-false-in-powershell-redirecting-stderr-to-stdout-gives-nativecommanderror/7571258 – Service