A co-worker today asked me how he could redirect output from an external executable into a variable. Seemed easy enough, you just do this:
$var = mycmd.exe
He tried it and got back a $null for his trouble. Turned out, the executable was writing to the error stream (STDERR) instead of STDOUT. Now, the question came up of how to capture that information.
We had to get a little old school because this is a DOS convention (well, much older than that but anyway) and has nothing to do with PowerShell. The answer wasn’t hard, but the response wasn’t what we expected. Observe:
PS > $a = netstat bob 2>&1 # cause intentional err and redirect PS > $a.GetType() IsPublic IsSerial Name BaseType -------- -------- ---- -------- True True Object[] System.Array PS > $a[0].GetType() IsPublic IsSerial Name BaseType -------- -------- ---- -------- True True ErrorRecord System.Object
I used “2>&1” to redirect the STDERR stream to the STDOUT stream. Worked fine, however when we tried to work with the results we found that it wasn’t a string array. Instead, as you see above, it is an array of ErrorRecord objects! In hindsight, that made sense to me. I mean, what else would you expect in the error stream but errors?
Anyway, long story short, the way to access the text inside of these error objects is by accessing the Exception property. But it was slightly more complex, as what you get is TWO errors. One with the “powershelly” NativeCommandError, and the second with the text that we needed. For example:
PS > $a[0]
netstat.exe :
At line:1 char:13
+ $a = netstat <<<< bob 2>&1 # cause intentional err and redirect
+ CategoryInfo : NotSpecified: (:String) [], RemoteException
+ FullyQualifiedErrorId : NativeCommandError
PS > $a[1].Exception
Displays protocol statistics and current TCP/IP network connections.
NETSTAT [-a] [-b] [-e] [-n] [-o] [-p proto] [-r] [-s] [-v] [interval]

[...] Working with STDERR [...]
[...] helpfully wraps STDERR output into exceptions. This is nice but I don’t need it! All I want is to see how a program worked by examining log [...]