Capture program stdout and stderr to separate variables





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}







33















Is it possible to redirect stdout from an external program to a variable and stderr from external programs to another variable in one run?



For example:



$global:ERRORS = @();
$global:PROGERR = @();

function test() {
# Can we redirect errors to $PROGERR here, leaving stdout for $OUTPUT?
$OUTPUT = (& myprogram.exe 'argv[0]', 'argv[1]');

if ( $OUTPUT | select-string -Pattern "foo" ) {
# do stuff
} else {
$global:ERRORS += "test(): oh noes! 'foo' missing!";
}
}

test;
if ( @($global:ERRORS).length -gt 0 ) {
Write-Host "Script specific error occurred";
foreach ( $err in $global:ERRORS ) {
$host.ui.WriteErrorLine("err: $err");
}
} else {
Write-Host "Script ran fine!";
}

if ( @($global:PROGERR).length -gt 0 ) {
# do stuff
} else {
Write-Host "External program ran fine!";
}


A dull example however I am wondering if that is possible?










share|improve this question

























  • You could use Start-Process to run myprogram.exe as described here. It captures STDOUT and STDERR separately.

    – Alexander Obersht
    Jun 14 '14 at 19:25




















33















Is it possible to redirect stdout from an external program to a variable and stderr from external programs to another variable in one run?



For example:



$global:ERRORS = @();
$global:PROGERR = @();

function test() {
# Can we redirect errors to $PROGERR here, leaving stdout for $OUTPUT?
$OUTPUT = (& myprogram.exe 'argv[0]', 'argv[1]');

if ( $OUTPUT | select-string -Pattern "foo" ) {
# do stuff
} else {
$global:ERRORS += "test(): oh noes! 'foo' missing!";
}
}

test;
if ( @($global:ERRORS).length -gt 0 ) {
Write-Host "Script specific error occurred";
foreach ( $err in $global:ERRORS ) {
$host.ui.WriteErrorLine("err: $err");
}
} else {
Write-Host "Script ran fine!";
}

if ( @($global:PROGERR).length -gt 0 ) {
# do stuff
} else {
Write-Host "External program ran fine!";
}


A dull example however I am wondering if that is possible?










share|improve this question

























  • You could use Start-Process to run myprogram.exe as described here. It captures STDOUT and STDERR separately.

    – Alexander Obersht
    Jun 14 '14 at 19:25
















33












33








33


5






Is it possible to redirect stdout from an external program to a variable and stderr from external programs to another variable in one run?



For example:



$global:ERRORS = @();
$global:PROGERR = @();

function test() {
# Can we redirect errors to $PROGERR here, leaving stdout for $OUTPUT?
$OUTPUT = (& myprogram.exe 'argv[0]', 'argv[1]');

if ( $OUTPUT | select-string -Pattern "foo" ) {
# do stuff
} else {
$global:ERRORS += "test(): oh noes! 'foo' missing!";
}
}

test;
if ( @($global:ERRORS).length -gt 0 ) {
Write-Host "Script specific error occurred";
foreach ( $err in $global:ERRORS ) {
$host.ui.WriteErrorLine("err: $err");
}
} else {
Write-Host "Script ran fine!";
}

if ( @($global:PROGERR).length -gt 0 ) {
# do stuff
} else {
Write-Host "External program ran fine!";
}


A dull example however I am wondering if that is possible?










share|improve this question
















Is it possible to redirect stdout from an external program to a variable and stderr from external programs to another variable in one run?



For example:



$global:ERRORS = @();
$global:PROGERR = @();

function test() {
# Can we redirect errors to $PROGERR here, leaving stdout for $OUTPUT?
$OUTPUT = (& myprogram.exe 'argv[0]', 'argv[1]');

if ( $OUTPUT | select-string -Pattern "foo" ) {
# do stuff
} else {
$global:ERRORS += "test(): oh noes! 'foo' missing!";
}
}

test;
if ( @($global:ERRORS).length -gt 0 ) {
Write-Host "Script specific error occurred";
foreach ( $err in $global:ERRORS ) {
$host.ui.WriteErrorLine("err: $err");
}
} else {
Write-Host "Script ran fine!";
}

if ( @($global:PROGERR).length -gt 0 ) {
# do stuff
} else {
Write-Host "External program ran fine!";
}


A dull example however I am wondering if that is possible?







windows powershell command-line stdout stderr






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Dec 9 '18 at 13:23









Ansgar Wiechers

146k13133191




146k13133191










asked Jun 14 '14 at 16:44









duszdusz

3831415




3831415













  • You could use Start-Process to run myprogram.exe as described here. It captures STDOUT and STDERR separately.

    – Alexander Obersht
    Jun 14 '14 at 19:25





















  • You could use Start-Process to run myprogram.exe as described here. It captures STDOUT and STDERR separately.

    – Alexander Obersht
    Jun 14 '14 at 19:25



















You could use Start-Process to run myprogram.exe as described here. It captures STDOUT and STDERR separately.

– Alexander Obersht
Jun 14 '14 at 19:25







You could use Start-Process to run myprogram.exe as described here. It captures STDOUT and STDERR separately.

– Alexander Obersht
Jun 14 '14 at 19:25














4 Answers
4






active

oldest

votes


















10














The easiest way to do this is to use a file for the stderr output, e.g.:



$output = & myprogram.exe 'argv[0]', 'argv[1]' 2>stderr.txt
$err = get-content stderr.txt
if ($LastExitCode -ne 0) { ... handle error ... }


I would also use $LastExitCode to check for errors from native console EXE files.






share|improve this answer





















  • 1





    It is important to point out (at least for stderr), the output is not what the command produces, but rather it is the hosts report of what the command-produced, which would come as a shock to those coming from other backgrounds.

    – Cameron Kerr
    Nov 13 '16 at 10:10











  • Since stderr.txt is probably used only once, New-TemporaryFile comes in handy

    – Franklin Yu
    May 1 '18 at 20:28





















30














One option is to combine the output of stdout and stderr into a single stream, then filter.



Data from stdout will be strings, while stderr produces System.Management.Automation.ErrorRecord objects.



$allOutput = & myprogram.exe 2>&1
$stderr = $allOutput | ?{ $_ -is [System.Management.Automation.ErrorRecord] }
$stdout = $allOutput | ?{ $_ -isnot [System.Management.Automation.ErrorRecord] }





share|improve this answer





















  • 7





    Or even better, replace the first line with & myprogram.exe 2>&1 | tee -Variable allOutput. That way you get the output printed for free, even keeping the order when stdout and stderr are interleaved (none of the other answers give that). This also doesn't go through any files which is a win in terms of performance and minimization of things that can fail.

    – Ohad Schneider
    Mar 22 '16 at 17:22








  • 2





    Combining @OhadSchneider's approach with capturing the output in a variable without outputting it: [Void] (& myprog.exe 2>&1 | tee -Variable allOutput) and then $stdout = $allOutput | ?{ $_ -isnot [System.Management.Automation.ErrorRecord] }.

    – ComFreek
    Aug 20 '17 at 11:07





















8














You should be using Start-Process with -RedirectStandardError -RedirectStandardOutput options. This other post has a great example of how to do this (sampled from that post below):



$pinfo = New-Object System.Diagnostics.ProcessStartInfo
$pinfo.FileName = "ping.exe"
$pinfo.RedirectStandardError = $true
$pinfo.RedirectStandardOutput = $true
$pinfo.UseShellExecute = $false
$pinfo.Arguments = "localhost"
$p = New-Object System.Diagnostics.Process
$p.StartInfo = $pinfo
$p.Start() | Out-Null
$p.WaitForExit()
$stdout = $p.StandardOutput.ReadToEnd()
$stderr = $p.StandardError.ReadToEnd()
Write-Host "stdout: $stdout"
Write-Host "stderr: $stderr"
Write-Host "exit code: " + $p.ExitCode





share|improve this answer





















  • 9





    This can deadlock an app that doesn't write asynchronously to stderr and stdout.

    – johnnycrash
    Aug 7 '14 at 17:48











  • @johnnycrash Any suggestion how to fix that?

    – sschuberth
    Sep 21 '15 at 10:59






  • 3





    Nevermind, as suggested here the WaitForExit() call should come after the ReadToEnd() calls.

    – sschuberth
    Sep 21 '15 at 11:14



















2














This is also an alternative that I have used to redirect stdout and stderr of a command line while still showing the output during PowerShell execution:



$command = "myexecutable.exe my command line params"

Invoke-Expression $command -OutVariable output -ErrorVariable errors
Write-Host "STDOUT"
Write-Host $output
Write-Host "STDERR"
Write-Host $errors


It is just another possibility to supplement what was already given.



Keep in mind this may not always work depending upon how the script is invoked. I have had problems with -OutVariable and -ErrorVariable when invoked from a standard command line rather than a PowerShell command line like this:



PowerShell -File ".FileName.ps1"


An alternative that seems to work under most circumstances is this:



$stdOutAndError = Invoke-Expression "$command 2>&1"


Unfortunately, you will lose output to the command line during execution of the script and would have to Write-Host $stdOutAndError after the command returns to make it "a part of the record" (like a part of a Jenkins batch file run). And unfortunately it doesn't separate stdout and stderr.






share|improve this answer


























    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f24222088%2fcapture-program-stdout-and-stderr-to-separate-variables%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    4 Answers
    4






    active

    oldest

    votes








    4 Answers
    4






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    10














    The easiest way to do this is to use a file for the stderr output, e.g.:



    $output = & myprogram.exe 'argv[0]', 'argv[1]' 2>stderr.txt
    $err = get-content stderr.txt
    if ($LastExitCode -ne 0) { ... handle error ... }


    I would also use $LastExitCode to check for errors from native console EXE files.






    share|improve this answer





















    • 1





      It is important to point out (at least for stderr), the output is not what the command produces, but rather it is the hosts report of what the command-produced, which would come as a shock to those coming from other backgrounds.

      – Cameron Kerr
      Nov 13 '16 at 10:10











    • Since stderr.txt is probably used only once, New-TemporaryFile comes in handy

      – Franklin Yu
      May 1 '18 at 20:28


















    10














    The easiest way to do this is to use a file for the stderr output, e.g.:



    $output = & myprogram.exe 'argv[0]', 'argv[1]' 2>stderr.txt
    $err = get-content stderr.txt
    if ($LastExitCode -ne 0) { ... handle error ... }


    I would also use $LastExitCode to check for errors from native console EXE files.






    share|improve this answer





















    • 1





      It is important to point out (at least for stderr), the output is not what the command produces, but rather it is the hosts report of what the command-produced, which would come as a shock to those coming from other backgrounds.

      – Cameron Kerr
      Nov 13 '16 at 10:10











    • Since stderr.txt is probably used only once, New-TemporaryFile comes in handy

      – Franklin Yu
      May 1 '18 at 20:28
















    10












    10








    10







    The easiest way to do this is to use a file for the stderr output, e.g.:



    $output = & myprogram.exe 'argv[0]', 'argv[1]' 2>stderr.txt
    $err = get-content stderr.txt
    if ($LastExitCode -ne 0) { ... handle error ... }


    I would also use $LastExitCode to check for errors from native console EXE files.






    share|improve this answer















    The easiest way to do this is to use a file for the stderr output, e.g.:



    $output = & myprogram.exe 'argv[0]', 'argv[1]' 2>stderr.txt
    $err = get-content stderr.txt
    if ($LastExitCode -ne 0) { ... handle error ... }


    I would also use $LastExitCode to check for errors from native console EXE files.







    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited yesterday









    Peter Mortensen

    13.9k1987113




    13.9k1987113










    answered Jun 14 '14 at 19:26









    Keith HillKeith Hill

    146k25267306




    146k25267306








    • 1





      It is important to point out (at least for stderr), the output is not what the command produces, but rather it is the hosts report of what the command-produced, which would come as a shock to those coming from other backgrounds.

      – Cameron Kerr
      Nov 13 '16 at 10:10











    • Since stderr.txt is probably used only once, New-TemporaryFile comes in handy

      – Franklin Yu
      May 1 '18 at 20:28
















    • 1





      It is important to point out (at least for stderr), the output is not what the command produces, but rather it is the hosts report of what the command-produced, which would come as a shock to those coming from other backgrounds.

      – Cameron Kerr
      Nov 13 '16 at 10:10











    • Since stderr.txt is probably used only once, New-TemporaryFile comes in handy

      – Franklin Yu
      May 1 '18 at 20:28










    1




    1





    It is important to point out (at least for stderr), the output is not what the command produces, but rather it is the hosts report of what the command-produced, which would come as a shock to those coming from other backgrounds.

    – Cameron Kerr
    Nov 13 '16 at 10:10





    It is important to point out (at least for stderr), the output is not what the command produces, but rather it is the hosts report of what the command-produced, which would come as a shock to those coming from other backgrounds.

    – Cameron Kerr
    Nov 13 '16 at 10:10













    Since stderr.txt is probably used only once, New-TemporaryFile comes in handy

    – Franklin Yu
    May 1 '18 at 20:28







    Since stderr.txt is probably used only once, New-TemporaryFile comes in handy

    – Franklin Yu
    May 1 '18 at 20:28















    30














    One option is to combine the output of stdout and stderr into a single stream, then filter.



    Data from stdout will be strings, while stderr produces System.Management.Automation.ErrorRecord objects.



    $allOutput = & myprogram.exe 2>&1
    $stderr = $allOutput | ?{ $_ -is [System.Management.Automation.ErrorRecord] }
    $stdout = $allOutput | ?{ $_ -isnot [System.Management.Automation.ErrorRecord] }





    share|improve this answer





















    • 7





      Or even better, replace the first line with & myprogram.exe 2>&1 | tee -Variable allOutput. That way you get the output printed for free, even keeping the order when stdout and stderr are interleaved (none of the other answers give that). This also doesn't go through any files which is a win in terms of performance and minimization of things that can fail.

      – Ohad Schneider
      Mar 22 '16 at 17:22








    • 2





      Combining @OhadSchneider's approach with capturing the output in a variable without outputting it: [Void] (& myprog.exe 2>&1 | tee -Variable allOutput) and then $stdout = $allOutput | ?{ $_ -isnot [System.Management.Automation.ErrorRecord] }.

      – ComFreek
      Aug 20 '17 at 11:07


















    30














    One option is to combine the output of stdout and stderr into a single stream, then filter.



    Data from stdout will be strings, while stderr produces System.Management.Automation.ErrorRecord objects.



    $allOutput = & myprogram.exe 2>&1
    $stderr = $allOutput | ?{ $_ -is [System.Management.Automation.ErrorRecord] }
    $stdout = $allOutput | ?{ $_ -isnot [System.Management.Automation.ErrorRecord] }





    share|improve this answer





















    • 7





      Or even better, replace the first line with & myprogram.exe 2>&1 | tee -Variable allOutput. That way you get the output printed for free, even keeping the order when stdout and stderr are interleaved (none of the other answers give that). This also doesn't go through any files which is a win in terms of performance and minimization of things that can fail.

      – Ohad Schneider
      Mar 22 '16 at 17:22








    • 2





      Combining @OhadSchneider's approach with capturing the output in a variable without outputting it: [Void] (& myprog.exe 2>&1 | tee -Variable allOutput) and then $stdout = $allOutput | ?{ $_ -isnot [System.Management.Automation.ErrorRecord] }.

      – ComFreek
      Aug 20 '17 at 11:07
















    30












    30








    30







    One option is to combine the output of stdout and stderr into a single stream, then filter.



    Data from stdout will be strings, while stderr produces System.Management.Automation.ErrorRecord objects.



    $allOutput = & myprogram.exe 2>&1
    $stderr = $allOutput | ?{ $_ -is [System.Management.Automation.ErrorRecord] }
    $stdout = $allOutput | ?{ $_ -isnot [System.Management.Automation.ErrorRecord] }





    share|improve this answer















    One option is to combine the output of stdout and stderr into a single stream, then filter.



    Data from stdout will be strings, while stderr produces System.Management.Automation.ErrorRecord objects.



    $allOutput = & myprogram.exe 2>&1
    $stderr = $allOutput | ?{ $_ -is [System.Management.Automation.ErrorRecord] }
    $stdout = $allOutput | ?{ $_ -isnot [System.Management.Automation.ErrorRecord] }






    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Oct 7 '15 at 21:49

























    answered Oct 7 '15 at 21:43









    Aaron SchultzAaron Schultz

    59557




    59557








    • 7





      Or even better, replace the first line with & myprogram.exe 2>&1 | tee -Variable allOutput. That way you get the output printed for free, even keeping the order when stdout and stderr are interleaved (none of the other answers give that). This also doesn't go through any files which is a win in terms of performance and minimization of things that can fail.

      – Ohad Schneider
      Mar 22 '16 at 17:22








    • 2





      Combining @OhadSchneider's approach with capturing the output in a variable without outputting it: [Void] (& myprog.exe 2>&1 | tee -Variable allOutput) and then $stdout = $allOutput | ?{ $_ -isnot [System.Management.Automation.ErrorRecord] }.

      – ComFreek
      Aug 20 '17 at 11:07
















    • 7





      Or even better, replace the first line with & myprogram.exe 2>&1 | tee -Variable allOutput. That way you get the output printed for free, even keeping the order when stdout and stderr are interleaved (none of the other answers give that). This also doesn't go through any files which is a win in terms of performance and minimization of things that can fail.

      – Ohad Schneider
      Mar 22 '16 at 17:22








    • 2





      Combining @OhadSchneider's approach with capturing the output in a variable without outputting it: [Void] (& myprog.exe 2>&1 | tee -Variable allOutput) and then $stdout = $allOutput | ?{ $_ -isnot [System.Management.Automation.ErrorRecord] }.

      – ComFreek
      Aug 20 '17 at 11:07










    7




    7





    Or even better, replace the first line with & myprogram.exe 2>&1 | tee -Variable allOutput. That way you get the output printed for free, even keeping the order when stdout and stderr are interleaved (none of the other answers give that). This also doesn't go through any files which is a win in terms of performance and minimization of things that can fail.

    – Ohad Schneider
    Mar 22 '16 at 17:22







    Or even better, replace the first line with & myprogram.exe 2>&1 | tee -Variable allOutput. That way you get the output printed for free, even keeping the order when stdout and stderr are interleaved (none of the other answers give that). This also doesn't go through any files which is a win in terms of performance and minimization of things that can fail.

    – Ohad Schneider
    Mar 22 '16 at 17:22






    2




    2





    Combining @OhadSchneider's approach with capturing the output in a variable without outputting it: [Void] (& myprog.exe 2>&1 | tee -Variable allOutput) and then $stdout = $allOutput | ?{ $_ -isnot [System.Management.Automation.ErrorRecord] }.

    – ComFreek
    Aug 20 '17 at 11:07







    Combining @OhadSchneider's approach with capturing the output in a variable without outputting it: [Void] (& myprog.exe 2>&1 | tee -Variable allOutput) and then $stdout = $allOutput | ?{ $_ -isnot [System.Management.Automation.ErrorRecord] }.

    – ComFreek
    Aug 20 '17 at 11:07













    8














    You should be using Start-Process with -RedirectStandardError -RedirectStandardOutput options. This other post has a great example of how to do this (sampled from that post below):



    $pinfo = New-Object System.Diagnostics.ProcessStartInfo
    $pinfo.FileName = "ping.exe"
    $pinfo.RedirectStandardError = $true
    $pinfo.RedirectStandardOutput = $true
    $pinfo.UseShellExecute = $false
    $pinfo.Arguments = "localhost"
    $p = New-Object System.Diagnostics.Process
    $p.StartInfo = $pinfo
    $p.Start() | Out-Null
    $p.WaitForExit()
    $stdout = $p.StandardOutput.ReadToEnd()
    $stderr = $p.StandardError.ReadToEnd()
    Write-Host "stdout: $stdout"
    Write-Host "stderr: $stderr"
    Write-Host "exit code: " + $p.ExitCode





    share|improve this answer





















    • 9





      This can deadlock an app that doesn't write asynchronously to stderr and stdout.

      – johnnycrash
      Aug 7 '14 at 17:48











    • @johnnycrash Any suggestion how to fix that?

      – sschuberth
      Sep 21 '15 at 10:59






    • 3





      Nevermind, as suggested here the WaitForExit() call should come after the ReadToEnd() calls.

      – sschuberth
      Sep 21 '15 at 11:14
















    8














    You should be using Start-Process with -RedirectStandardError -RedirectStandardOutput options. This other post has a great example of how to do this (sampled from that post below):



    $pinfo = New-Object System.Diagnostics.ProcessStartInfo
    $pinfo.FileName = "ping.exe"
    $pinfo.RedirectStandardError = $true
    $pinfo.RedirectStandardOutput = $true
    $pinfo.UseShellExecute = $false
    $pinfo.Arguments = "localhost"
    $p = New-Object System.Diagnostics.Process
    $p.StartInfo = $pinfo
    $p.Start() | Out-Null
    $p.WaitForExit()
    $stdout = $p.StandardOutput.ReadToEnd()
    $stderr = $p.StandardError.ReadToEnd()
    Write-Host "stdout: $stdout"
    Write-Host "stderr: $stderr"
    Write-Host "exit code: " + $p.ExitCode





    share|improve this answer





















    • 9





      This can deadlock an app that doesn't write asynchronously to stderr and stdout.

      – johnnycrash
      Aug 7 '14 at 17:48











    • @johnnycrash Any suggestion how to fix that?

      – sschuberth
      Sep 21 '15 at 10:59






    • 3





      Nevermind, as suggested here the WaitForExit() call should come after the ReadToEnd() calls.

      – sschuberth
      Sep 21 '15 at 11:14














    8












    8








    8







    You should be using Start-Process with -RedirectStandardError -RedirectStandardOutput options. This other post has a great example of how to do this (sampled from that post below):



    $pinfo = New-Object System.Diagnostics.ProcessStartInfo
    $pinfo.FileName = "ping.exe"
    $pinfo.RedirectStandardError = $true
    $pinfo.RedirectStandardOutput = $true
    $pinfo.UseShellExecute = $false
    $pinfo.Arguments = "localhost"
    $p = New-Object System.Diagnostics.Process
    $p.StartInfo = $pinfo
    $p.Start() | Out-Null
    $p.WaitForExit()
    $stdout = $p.StandardOutput.ReadToEnd()
    $stderr = $p.StandardError.ReadToEnd()
    Write-Host "stdout: $stdout"
    Write-Host "stderr: $stderr"
    Write-Host "exit code: " + $p.ExitCode





    share|improve this answer















    You should be using Start-Process with -RedirectStandardError -RedirectStandardOutput options. This other post has a great example of how to do this (sampled from that post below):



    $pinfo = New-Object System.Diagnostics.ProcessStartInfo
    $pinfo.FileName = "ping.exe"
    $pinfo.RedirectStandardError = $true
    $pinfo.RedirectStandardOutput = $true
    $pinfo.UseShellExecute = $false
    $pinfo.Arguments = "localhost"
    $p = New-Object System.Diagnostics.Process
    $p.StartInfo = $pinfo
    $p.Start() | Out-Null
    $p.WaitForExit()
    $stdout = $p.StandardOutput.ReadToEnd()
    $stderr = $p.StandardError.ReadToEnd()
    Write-Host "stdout: $stdout"
    Write-Host "stderr: $stderr"
    Write-Host "exit code: " + $p.ExitCode






    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited yesterday









    Peter Mortensen

    13.9k1987113




    13.9k1987113










    answered Jun 15 '14 at 6:49









    AckSynFoolAckSynFool

    915




    915








    • 9





      This can deadlock an app that doesn't write asynchronously to stderr and stdout.

      – johnnycrash
      Aug 7 '14 at 17:48











    • @johnnycrash Any suggestion how to fix that?

      – sschuberth
      Sep 21 '15 at 10:59






    • 3





      Nevermind, as suggested here the WaitForExit() call should come after the ReadToEnd() calls.

      – sschuberth
      Sep 21 '15 at 11:14














    • 9





      This can deadlock an app that doesn't write asynchronously to stderr and stdout.

      – johnnycrash
      Aug 7 '14 at 17:48











    • @johnnycrash Any suggestion how to fix that?

      – sschuberth
      Sep 21 '15 at 10:59






    • 3





      Nevermind, as suggested here the WaitForExit() call should come after the ReadToEnd() calls.

      – sschuberth
      Sep 21 '15 at 11:14








    9




    9





    This can deadlock an app that doesn't write asynchronously to stderr and stdout.

    – johnnycrash
    Aug 7 '14 at 17:48





    This can deadlock an app that doesn't write asynchronously to stderr and stdout.

    – johnnycrash
    Aug 7 '14 at 17:48













    @johnnycrash Any suggestion how to fix that?

    – sschuberth
    Sep 21 '15 at 10:59





    @johnnycrash Any suggestion how to fix that?

    – sschuberth
    Sep 21 '15 at 10:59




    3




    3





    Nevermind, as suggested here the WaitForExit() call should come after the ReadToEnd() calls.

    – sschuberth
    Sep 21 '15 at 11:14





    Nevermind, as suggested here the WaitForExit() call should come after the ReadToEnd() calls.

    – sschuberth
    Sep 21 '15 at 11:14











    2














    This is also an alternative that I have used to redirect stdout and stderr of a command line while still showing the output during PowerShell execution:



    $command = "myexecutable.exe my command line params"

    Invoke-Expression $command -OutVariable output -ErrorVariable errors
    Write-Host "STDOUT"
    Write-Host $output
    Write-Host "STDERR"
    Write-Host $errors


    It is just another possibility to supplement what was already given.



    Keep in mind this may not always work depending upon how the script is invoked. I have had problems with -OutVariable and -ErrorVariable when invoked from a standard command line rather than a PowerShell command line like this:



    PowerShell -File ".FileName.ps1"


    An alternative that seems to work under most circumstances is this:



    $stdOutAndError = Invoke-Expression "$command 2>&1"


    Unfortunately, you will lose output to the command line during execution of the script and would have to Write-Host $stdOutAndError after the command returns to make it "a part of the record" (like a part of a Jenkins batch file run). And unfortunately it doesn't separate stdout and stderr.






    share|improve this answer






























      2














      This is also an alternative that I have used to redirect stdout and stderr of a command line while still showing the output during PowerShell execution:



      $command = "myexecutable.exe my command line params"

      Invoke-Expression $command -OutVariable output -ErrorVariable errors
      Write-Host "STDOUT"
      Write-Host $output
      Write-Host "STDERR"
      Write-Host $errors


      It is just another possibility to supplement what was already given.



      Keep in mind this may not always work depending upon how the script is invoked. I have had problems with -OutVariable and -ErrorVariable when invoked from a standard command line rather than a PowerShell command line like this:



      PowerShell -File ".FileName.ps1"


      An alternative that seems to work under most circumstances is this:



      $stdOutAndError = Invoke-Expression "$command 2>&1"


      Unfortunately, you will lose output to the command line during execution of the script and would have to Write-Host $stdOutAndError after the command returns to make it "a part of the record" (like a part of a Jenkins batch file run). And unfortunately it doesn't separate stdout and stderr.






      share|improve this answer




























        2












        2








        2







        This is also an alternative that I have used to redirect stdout and stderr of a command line while still showing the output during PowerShell execution:



        $command = "myexecutable.exe my command line params"

        Invoke-Expression $command -OutVariable output -ErrorVariable errors
        Write-Host "STDOUT"
        Write-Host $output
        Write-Host "STDERR"
        Write-Host $errors


        It is just another possibility to supplement what was already given.



        Keep in mind this may not always work depending upon how the script is invoked. I have had problems with -OutVariable and -ErrorVariable when invoked from a standard command line rather than a PowerShell command line like this:



        PowerShell -File ".FileName.ps1"


        An alternative that seems to work under most circumstances is this:



        $stdOutAndError = Invoke-Expression "$command 2>&1"


        Unfortunately, you will lose output to the command line during execution of the script and would have to Write-Host $stdOutAndError after the command returns to make it "a part of the record" (like a part of a Jenkins batch file run). And unfortunately it doesn't separate stdout and stderr.






        share|improve this answer















        This is also an alternative that I have used to redirect stdout and stderr of a command line while still showing the output during PowerShell execution:



        $command = "myexecutable.exe my command line params"

        Invoke-Expression $command -OutVariable output -ErrorVariable errors
        Write-Host "STDOUT"
        Write-Host $output
        Write-Host "STDERR"
        Write-Host $errors


        It is just another possibility to supplement what was already given.



        Keep in mind this may not always work depending upon how the script is invoked. I have had problems with -OutVariable and -ErrorVariable when invoked from a standard command line rather than a PowerShell command line like this:



        PowerShell -File ".FileName.ps1"


        An alternative that seems to work under most circumstances is this:



        $stdOutAndError = Invoke-Expression "$command 2>&1"


        Unfortunately, you will lose output to the command line during execution of the script and would have to Write-Host $stdOutAndError after the command returns to make it "a part of the record" (like a part of a Jenkins batch file run). And unfortunately it doesn't separate stdout and stderr.







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Jan 3 at 20:11









        Peter Mortensen

        13.9k1987113




        13.9k1987113










        answered Aug 10 '16 at 20:43









        James EbyJames Eby

        1,1111323




        1,1111323






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f24222088%2fcapture-program-stdout-and-stderr-to-separate-variables%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Monofisismo

            Angular Downloading a file using contenturl with Basic Authentication

            Olmecas