다음을 통해 공유


PowerShell StdOut go out, StdErr go everywhere

 

While becoming familiar and a really big fan of PowerShell, I faced the following issue. During a migration project doing bulk migrations, I needed information Messages (coming to StdOut) as well as error message (coming to StdErr) displayed to the Console. Well that is quite easy as being the standard behavior. The challenge was, that error in addition needed to be duplicated in an error file, that in case of an error you can simply grab all the non 0kb files and do through them in order to investigate the errors.

It sorted out that this wasn´t easy at all as the output once being redirected cannot be easily duplicated.

There were actually solution (which I could post as well if you are interested) including the tee object as well as the option to create a wrapper script, redirect the error output, read it at the end of the execution and write it to the console. But this wouldnß´t be as natural as having the error message at the exact place where it happens (which could somewhere in between).

My colleague Dongbo Wang then pointed me in the right direction. For an easier repro as well as giving him the credits for this idea, here is what we came up with:

The sample execution file contains several command, simulating normal messages as well as an error message:

 

 Write-Output "Before the error" 
 Write-Output "================" 
 Write-Error "Here is the error" 
 Write-Output "================" 
 Write-Output "After the error"
  
  

For this sample we should be able to see the error message after the "Before" message and Before the after message.

So save the above made statements to a script file psscript.ps1 and execute it with the following command:

 

 .\psscript.ps1 2>&1 | % { if ($_ -is [System.Management.Automation.ErrorRecord]) 
 { $_ | Out-File -Append .\Errors.txt } $_ }

 

So what happens here ? The messages (being objects) are piped and checked for their message type; if being of type [System.Management.Automation.ErrorRecord] they are collected and appended in a loop to the specified output error file. So what we get here is the output of

image

 

and the error message within the created text file Errors.txt:

 

image

 

-Jens

Comments

  • Anonymous
    June 12, 2013
    Geat job! You saved me :) Thanks

  • Anonymous
    March 23, 2015
    Remember that stdout is buffered, while stderror is not.  If you want to ensure the timing of stdout, you need to flush the buffer in your code.

  • Anonymous
    March 24, 2015
    Good catch, thanks for sharing the information.