CLR
CLR

Reputation: 341

Capture EXE output in PowerShell

A little background first.

I've been tasked with encrypting files with a Powershell script using GPG (gnupg.org). The specific exe I'm calling is simply gpg.exe. I'd like to capture the output whenever I execute a command.

For instance, I import a public key in powershell as follows:

& $gpgLocation --import "key.txt"

$gpgLocation is simply the file location of gpg.exe (default being "C:\Program Files\GNU\GnuPG\gpg.exe"

My entire issue here is that if I try:

& $gpgLocation --import "key.txt" | out-file gpgout.txt

All I get is a 1kb file, named appropriately, but it is COMPLETELY blank. I've tried several flags for out-file just to see if I was running into a quirk.

I've also tried sending the command to this code (and capturing the output with the usual out-file etc):

param
(
    [string] $processname, 
    [string] $arguments
)

$processStartInfo = New-Object System.Diagnostics.ProcessStartInfo;
$processStartInfo.FileName = $processname;
$processStartInfo.WorkingDirectory = (Get-Location).Path;
if($arguments) { $processStartInfo.Arguments = $arguments }
$processStartInfo.UseShellExecute = $false;
$processStartInfo.RedirectStandardOutput = $true;

$process = [System.Diagnostics.Process]::Start($processStartInfo);
$process.WaitForExit();
$process.StandardOutput.ReadToEnd();

Any ideas? I'm desperate!

Upvotes: 29

Views: 48019

Answers (5)

jhamm
jhamm

Reputation: 1888

Stobor's answer is great. I am adding to his answer because I needed to perform additional actions if the exe had an error.

You can also store the output of the exe into a variable like this. Then you can do error handling based on the result of the exe.

$out = $gpgLocation --import "key.txt" 2>&1
if($out -is [System.Management.Automation.ErrorRecord]) {
    # email or some other action here
    Send-MailMessage -to [email protected] -subject "Error in gpg " -body "Error:`n$out" -from [email protected] -smtpserver smtp.example.com
}
$out | out-file gpgout.txt

Upvotes: 6

vamsu
vamsu

Reputation: 101

You also can use Out-Host as shown below.

& $gpgLocation --import "key.txt" | Out-Host

Upvotes: 10

Robert Harvey
Robert Harvey

Reputation: 180788

You need to use the --batch switch when automating GPG.EXE, as in:

& $gpgLocation --import "key.txt" --batch | out-file gpgout.txt

Without that switch, GPG may be waiting for user input.

Upvotes: 3

Josh
Josh

Reputation: 69262

Also, PowerShell simply can't capture the output of some programs because they don't write to stdout. You can verify this by running the program in PowerShell ISE (it's in the version 2.0 CTP 3)

If PowerShell ISE can't show the output in the graphical console, then you can't capture it either and may need some other way of automating the program.

Upvotes: 3

Stobor
Stobor

Reputation: 45122

Does the output you're expecting go to standard-error or standard-out?

does this work?

& $gpgLocation --import "key.txt" 2>&1 | out-file gpgout.txt

Upvotes: 37

Related Questions