In PowerShell, I'm unable to write error stream output to a variable.
Running the command without saving the output to a variable will result in output from any stream being visible, but alas, I require the output to be written to a variable.
& terraform $action $arguments
Initially I started using this. However, only the success stream is written to the variable (as expected).
$res = & terraform $action $arguments
So I consulted the docs for about_Redirection, but the trouble is, when I redirect the error stream (or all streams) to the success stream, I still only see the success stream written to the variable. I've made several attempts, all of which failed.
$res = & terraform $action $arguments 2>&1
$res = & terraform $action $arguments *>&1
$res = & terraform $action $arguments *>&1 | ForEach-Object { $_.ToString() }
However, of if I redirect the error stream to a file then the stream is written as expected.
$res = & terraform $action $arguments 2>> terraform-errors.log
How can I write the output from all streams to a variable?
I've finally found the answer to this, and the issue is due to the setting $ErrorActionPreference = Stop
.
When a terminating occurs, the script is killed before the output is redirected. To get around this, the error action preference must be changed and then errors and output can be sent to to variables using Invoke-Expression
and some common parameters.
$ErrorActionPreference = "SilentlyContinue"
Invoke-Expression "& terraform $action $arguments 2>&1" -ErrorVariable terraformError -OutVariable terraformState | Out-Null
$ErrorActionPreference = "Stop"
### Check if there was an error.
if ($terraformError) {
throw $terraformError
}
-ErrorAction
to change the error action preference?Sadly -ErrorAction
only works with non-terminating errors. Because the error action preference for the script is Stop
, this means that the Invoke-Expression
command will always trigger a terminating error regardless of the value of the -ErrorAction
common parameter.
To get around this, the error action preference must be changed before the Invoke-Expression
command is run, and then changed back after it's finished.
Out-Null
?Despite saving errors and output to variables, output would also be streamed to the console without piping it to Out-Null
.
Obviously this is optional as in some cases in may be acceptable/expected that output would also be streamed to the console.