I have read here that when you run external commands in powershell, their output is always interpreted as a string or string array: https://stackoverflow.com/a/35980675/983442
I'm trying to process binary output from an external command, but it seems like PowerShell can only give me strings.
This leaves me wondering, what encoding is used to convert the binary data into strings? And also, how does it interpret newlines in order to divide the binary data into a string array? It seems to be splitting on the \n
character alone, but I'm sure it would also split on \r\n
.
Is there even a reliable way to take the strings powershell gives me and turn them back into a byte array?
For example, let's say I have a batch file with the following contents, call it thing.bat
:
@echo off
type image.jpg
I then run the following powershell:
PS> $x = & .\thing.bat
PS> $x.gettype()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True Object[] System.Array
PS> $x[0].gettype()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True String System.Object
PS> $x.count
36
How can I reliably recreate this image.jpg in PowerShell once I have the $x
variable?
PowerShell assumes, that every external program called by you provides only
string
s over it's output stream. While this is not so far from reality, one might want to get the real bytes from an external program. To achieve that, we will create a new process "from scratch"Which provides us a
StreamReader
forStandardOutput
andStandardError
, when the respective Redirect properties are set to$true
.Now to get the stream's content we could easily use
ReadToEnd()
like$outContent = $proc.StandardOutput.ReadToEnd()
, but that would give us just a string again.A
StreamReader
gives us the following methods (amongst others):Just create and pass a
char[]
buffer toRead()
and use it like you want:A second - easier but less flexible solution:
If you don't have a problem writing files to disk you could easily redirect the program's standard output to a file with
-Encoding Oem
and read it in again withGet-Content
: