I have the following files:
test.ps1
& e:\test.bat > stdout.txt 2> stderr.txt
test.bat
@echo off
echo write to stdout
echo write to stderr >&2
When I call test.ps1
like this:
powershell -ExecutionPolicy bypass e:\test.ps1
The output files look like this:
stdout.txt
write argument to stdout
stderr.txt
test.bat : write to stderr
At E:\test.ps1:5 char:1
+ & "$application" "$argument" > $stdout 2> $stderr
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (write to stderr :String) [], RemoteException
+ FullyQualifiedErrorId : NativeCommandError
There is an answer how to prevent the NativeCommandError output from being written to file when redirecting both stdout and stderr to the same file, but how can I achieve that when writing to different files?
To build on the helpful comments:
In PowerShell (Core) 7+, your command would work as expected.
In Windows PowerShell, unfortunately, stderr lines are implicitly formatted as if they were PowerShell errors when a 2>
redirection is involved, resulting in the noisy output you saw.
The solution is to merge stderr into stdout with 2>&1
, and separate the collected lines into stdout and stderr by their type, allowing you to stringify the stderr lines, which PowerShell wraps in [System.Management.Automation.ErrorRecord]
instances, via their .ToString()
method, which results in their text content only.
Apart from being cumbersome, this approach requires collecting all output in memory first.
$stdout, $stderr = (& e:\test.bat 2>&1).Where({ $_ -is [string] }, 'Split')
$stdout > stdout.txt
$stderr.ForEach('ToString') > stderr.txt