Both version 1 and version 2 of Windows PowerShell have a nasty limitation when it comes to capturing *all* output from a script. First up, within a script there is no way to redirect host (Write-Host), verbose, warning and debug message to a log file. There is a mechanism within PowerShell that allows you to capture these streams of information – Start-Transcript. At first blush, this seems promising however the wheels fall off pretty quickly primarily because Start-Transcript doesn’t capture the output of EXEs. So all that output from compilers, build tools, etc doesn’t get captured. That’s a huge, gaping hole. Furthermore, Start-Transcript is really aimed at capturing your entire PowerShell session. It isn’t particularly suited for script logging. For instance, some folks including myself use Start-Transcript in their profile to capture an entire PowerShell session. This is very handy when you need to look up how you did something previously which is possible because you can search your transcript files. However, if you start a script that blindly calls Start-Transcript it will error. You can only call Start-Transcript if it hasn’t already been started . There is no notion of nested transcripts.
If you find these limitations as annoying as I do, please vote on them via the Microsoft Connect site:
https://connect.microsoft.com/feedback/ViewFeedback.aspx?FeedbackID=283088&SiteID=99
https://connect.microsoft.com/feedback/ViewFeedback.aspx?FeedbackID=297055&SiteID=99
For now, the best way to accomplish this is to use a host that can capture all PowerShell output. It turns out that executing the script through another instance of PowerShell.exe will allow you to capture all the output. For instance, consider the following script (test.ps1) that exercises the various output streams:
1: $DebugPreference = 2
2: $VerbosePreference = 2
3: $WarningPreference = 2
4:
5: hostname.exe
6: Write-Host "host"
7: Write-Output "output"
8: Write-Error "error"
9: Write-Verbose "verbose"
10: Write-Warning "warning"
11: Write-Debug "debug"
If you run the following you can easily capture all PowerShell output as shown below:
PS> powershell.exe -noprofile -file test.ps1 > test.log
PS> Get-Content test.log
HILLR1
host
output
C:\Users\hillr\Bin\test.ps1 : error
+ CategoryInfo : NotSpecified: (:) [Write-Error], WriteErrorException
+ FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,test.ps1 host
VERBOSE: verbose
WARNING: warning
DEBUG: debug
|
Updated 3/7/09: Aleksandar pointed out that you can just use Powershell.exe. No need to go through cmd.exe. Thanks!
psmdtag:script – Logging output
Thanks for this! I’m fairly inexperienced with PowerShell. I’ve used it infrequently in the past. Using what I learned from your blog, I was able to figure out a problem that I’d been having when I was launching my script from the standard Windows command prompt.
This answer here worked better for me…
http://blogs.msdn.com/b/powershell/archive/2010/01/04/workaround-for-start-transcript-on-native-processes.aspx
Pingback: Piping powershell messages to Write-EventLog - Admins Goodies
the write-error output does not show up in my test.log
I have to correct myself. it works during a PS Session. I’d like to make a shortcut that runs test.ps1 and logs to test.log. Any Ideas?
cmd.exe /c powershell.exe -file test.ps1 > test.log
Does not work with UNC paths though.
Actually I need something like teeing. Want the Output on the Screen and in the logfile. And all this started by a shortcut.
Hi mister,
I use Powershell remoting, and I would like log to file (any few messages, the rest to output console)
Which is the better manner for log to a file using powershell?
Maybe Andy Arismendi: http://poshcode.org/3270
Suggestions? thanks
I recently had the same problem with logging all commands to a file.
Solution and code snippet is here: http://www.rubaniuk.com/?p=113
Nice!
Pingback: Powershell notes. Part 1 | Automate IT!
Pingback: Capturing the String Output of Get-CsPoolFabricState on Lync Server | Tom Talks UC
Doesn’t work for interactive read-host prompts.
Logging the output in a log file worked well for me. Thank you