tl;dr
Call the .ToString()
method on each output object to ensure string-only output (%
, the built-in alias of ForEach-Object
is used for brevity):
node . 2>&1 | % ToString
Caveat:
Capturing output from external programs or piping it to another command invariably subjects it to decoding into .NET strings, which can reveal a mismatch between the actual character encoding a given program uses and the one PowerShell uses for decoding, as reflected in [Console]::OutputEncoding
, which itself defaults to the console's active code page.
Thus, you may have to (temporarily) set [Console]::OutputEncoding
to the actual encoding to ensure correct interpretation.
Indeed, given that node
invariably produces UTF-8-encoded output, you'll need to (temporarily) set
[Console]::OutputEncoding = [System.Text.UTF8Encoding]::new()
if your output comprises non-ASCII characters - see this answer for details.
Background information
By using PowerShell's 2>&1
redirection, a single stream of objects containing the merged stdout and stderr lines of the external program is sent to the success output stream.
While the objects representing stdout lines are strings, those representing stderr lines are [System.Management.Automation.ErrorRecord]
instances.
In Windows PowerShell, these [ErrorRecord]
instances render like PowerShell errors, which is what you saw. This is unfortunate, because stderr output may or may not represent actual errors, given that stderr is more generally used for anything that isn't data, such as status information.
Fortunately, this display problem has been fixed in PowerShell (Core) 7+.[1]
As an aside: That PowerShell uses distinct data types for stdout vs. stderr lines actually offers an advantage: If you capture the resulting objects, you can determine each object's stream of origin via its data type (-is [string]
vs. -is [System.Management.Automation.ErrorRecord]
)
See also:
- For a comprehensive discussion of redirecting output from external programs in PowerShell, see this answer.
[1] In the context of PowerShell remoting, however, [System.Management.Automation.ErrorRecord]
still render as if they were errors, though in v7+ in a much subtler form: their text prints in red as-is, without the extra information and multi-line representation seen in Windows PowerShell.