Created
May 25, 2022 11:56
-
-
Save jhoneill/b872f3e8a8433731a7373bdd99b00d72 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function binaryout { | |
<# | |
.SYNOPSIS | |
Workaround for PowerShell processing the output of all external programs as strings | |
.DESCRIPTION | |
PowerShell treats any output from an external program as string which should be | |
split whenever it sees LF or CR LF. As a workround this calls the program with | |
Start-Process and redirects standard output to a file - on completion the file | |
is read and sent as a bytestream to the next process. | |
Optionally the file can be named and retained - like a tee operation, and when | |
this is done the output can be surpressed | |
.EXAMPLE | |
binaryout curl.exe "https://jhoneill.github.io/assets/james.jpg" | Set-Content -AsByteStream -Path .\james.jpg | |
Uses curl to get a jpg file and sends it to file - note that > is the equivalent of | |
Set-content without -AsByteSteam and will cause the bytes to be treated as strings | |
.EXAMPLE | |
binaryout curl.exe "https://jhoneill.github.io/assets/james.jpg" -teefile .\avatar.jpg -NoOutput | |
if the only requirement is to get a file then using the tee option with no output will do that. | |
#> | |
[cmdletbinding(PositionalBinding=$false,DefaultParameterSetName='MakeTmpFile')] | |
param ( | |
#Filepath to pass to Start process (i.e. the command) | |
[Parameter(Position=0)] | |
[string]$FilePath, | |
#If specified keeps the temporary file effectively doing a TEE | |
[Parameter(ParameterSetName='UseTeeFile',Mandatory=$true)] | |
[String]$TeeFile, | |
#If specified with -TeeFile doesn't output the results | |
[Parameter(ParameterSetName='UseTeeFile')] | |
[switch]$NoOutput, | |
#Arguments to pass to Start-Process - collects the rest of the command line | |
[Parameter(ValueFromRemainingArguments)] | |
$Argumentlist | |
) | |
process { | |
if ($TeeFile) {$tempPath = $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath( $TeeFile )} | |
else {$tempPath = [System.IO.Path]::GetTempFileName()} | |
Start-Process -NoNewWindow -FilePath $FilePath -ArgumentList $Argumentlist -RedirectStandardOutput $temppath | |
Write-Host "" | |
if (-not $NoOutput) { | |
$tries = 0 | |
#The file can take a moment to close re-try at 1/10th sec intervals, give up after 10 | |
while ($tries -lt 10) { | |
try { [System.IO.File]::ReadAllBytes($temppath) | |
break | |
} | |
catch { | |
$tries ++ | |
Start-Sleep -Milliseconds 100 | |
} | |
} | |
if (-not $TeeFile) {Remove-Item $tempPath -Force -ErrorAction SilentlyContinue} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment