Alan
Alan

Reputation: 43

in powershell how do I grab command output while piping a variable into the command?

Is there a powershell cmdlet which redirects console output into a variable (NOT a file)?

I need to pass the content of a variable into a binary's command line, and collect the binary's console response in another variable, but can't figure out how.

For example, Perforce's p4.exe returns an OK status with a text error message when this fails

$MyP4Client | p4 client -i

To abort on error I need to put a try/catch round that, then collect and check the console output from p4. When there's no input redirection involved, I can do this to get p4's console output into a variable:

Try {
    $P4response = & 'p4' sync -f //depot/myfiles/...   2>&1
}
Catch {
    ExitWithCode 1 # abort
}
if( $P4response -match "blah" ) {
    # act on p4 response text

but I'm failing dismally at finding a way to both feed the $MyP4Client variable into the p4 binary then grab the output from p4. Among many other attempts, none of these get p4's output into $P4response :

$P4response = $p4ClientSpec | & 'p4' client -i 
$P4response = ( $p4ClientSpec | p4 client -i )
$P4response = { $p4ClientSpec | & 'p4' client -i }
$p4ClientSpec | & 'p4' "client -i" | $P4response  

The last gets a parser error ($P4response is an expression). It's pretty obvious I'm missing something! What's going to work, please? Thanks

Upvotes: 0

Views: 1123

Answers (3)

mjolinor
mjolinor

Reputation: 68341

If the executable is actually writing the error to stderr, it seems like you'd have picked it up by now with what you've already tried. If it's just writing a message directly to the console then your only option may be to use Start-Transcript to capture the console output to a file, and the parse the file contents looking for that message.

Upvotes: 0

Duncan
Duncan

Reputation: 95732

Your question implies you are trying to catch output to stderr as well as stdout. This should work:

$P4response = ( $p4ClientSpec | p4 client -i  2>&1 )

You will get both the stdout and stderr from the console app in the variable, but you can separate them again quite easily:

$output = $P4Response | Where-Object { $_.GetType() -ne [System.Management.Automation.ErrorRecord] }
$errors = $P4Response | Where-Object { $_.GetType() -eq [System.Management.Automation.ErrorRecord] }

and then you just check for non-empty $errors.

Upvotes: 2

vonPryz
vonPryz

Reputation: 24091

Try Tee-Object cmdlet. It saves command output in a file or variable and also sends it down the pipeline. Docs at Technet.

Upvotes: 0

Related Questions