Powershell ISE incorrectly interprets openssl.exe stdout as error
I'm trying to debug a script in ISE PowerShell, but I'm running into an issue where normal line output is interpreted as ISE error
I was able to simplify reproducing this problem: I get any version of opensl at https://www.openssl.org/related/binaries.html (I tested this with 1.0.2d x86 from the linked repository http://slproweb.com/products/ Win32OpenSSL.html )
I open ISS Powershell, navigate to where the exe is and run the following:
$ErrorActionPreference = "Stop"
$env:OPENSSL_CONF = ((Resolve-Path "openssl.cfg").Path)
&openssl.exe genrsa
The exit is red and starts like this:
openssl.exe : Loading 'screen' into random state - done
At line:1 char:1
+ &C:\Trayport\OpenSsl\openssl.exe genrsa
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (Loading 'screen...om state - done:String) [], RemoteException
+ FullyQualifiedErrorId : NativeCommandError
Generating RSA private key, 2048 bit long modulus
If I run this in a normal PowerShell command window, the output is the same but white and not considered an error
Loading 'screen' into random state - done
Generating RSA private key, 2048 bit long modulus
I tried to use 2> 1 and enable the call with the ErrorPreference parameter (as suggested in PowerShell ISE throws git error message) but it still fails
try / catching the whole exception works, but I would prefer to avoid it.
I have tried using PowerShell 3.0 and 4.0
Edit: if you use $ErrorActionPreference = "SilentlyContinue"
it disables this error, but then you lose access to the exit and also the legitimate problems go away.
source to share
I found a working solution.
As pointed out in the edit to the question, installing $ErrorActionPreference = "SilentlyContinue"
is a bit of a wrong solution as in this case the PowerShell equivalent to swallow all errors and also removes access to the actual result of the process.But when testing with parameters for a command that would actually return a legitimate error, I noticed, that in this case I get non-0 $ LASTEXITCODE (note everyone else who has a similar problem: this is indeed specific to openssl.exe, it might not be the same as for any application you call).
So I decided to rely on the process exit code to decide if stderr should be treated as an actual error.
Capturing standard errors and errors with Start-Process provides a solution to keep the output of a process running, so:
$processStartInfo = New-Object System.Diagnostics.ProcessStartInfo
$processStartInfo.FileName = "openssl.exe"
$processStartInfo.RedirectStandardError = $true
$processStartInfo.RedirectStandardOutput = $true
$processStartInfo.UseShellExecute = $false
$processStartInfo.Arguments = "genrsa"
$process = New-Object System.Diagnostics.Process
$process.StartInfo = $processStartInfo
$process.Start() | Out-Null
$process.WaitForExit()
$standardError = $process.StandardError.ReadToEnd()
if ($process.ExitCode) {
Write-Error $standardError
} else {
Write-Host $standardError
}
source to share
Powershell interprets any dump in the error channel as an error that occurred from the side of the application, so it stops the script at that point. You have to add 2>&1
to the line that calls openssl.exe
so that the standard error of the application will not be caught and interpreted by Powershell as an actual error.
$ErrorActionPreference = "Stop"
$env:OPENSSL_CONF = ((Resolve-Path "openssl.cfg").Path)
& openssl.exe genrsa 2>&1
UPDATE: it is incurable, as it is, Powershell ISE catches standard error in Write-Error
and triggers stop. There is one here , which involves porting an external application that generates the error channel output to a script block with a local override , for example: $ErrorActionPreference
& {
$ErrorActionPreference='silentlycontinue'
openssl.exe genrsa 2>&1
}
source to share