Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
523 views
in Technique[技术] by (71.8m points)

trace - PowerShell Tee-Object not capturing debug lines in file

I have a PowerShell script that runs via automation, so I need to capture the output of the script to a file, but I'd also like to capture the commands that were run, to give the output some context (I'd use set -x in a Linux shell script). I can't figure out how to capture those commands into the output file in Windows though; any help is much appreciated!

# script.ps1

Set-PSDebug -Trace 1
Write-Host "Hello, World!"

How I'm calling the script (from cmd):

$ powershell -command "./script.ps1 *>&1 | Tee-Object -FilePath ./output.txt"

Terminal output:

DEBUG:    2+  >>>> Write-Host "Hello, World!"
Hello, World!

output.txt file contents:

Hello, World!

You can see that the output file is missing the debug line that was shown in the terminal. Ideally, I'd like the debug lines to only be in the output file (not the terminal output), but having the debug lines in both places would be fine too.

Note that PowerShell 5.1 is the version I have installed.

question from:https://stackoverflow.com/questions/65943627/powershell-tee-object-not-capturing-debug-lines-in-file

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Unfortunately, PowerShell's tracing output (activated via Set-PSDebug) operates outside PowerShell's system of output streams, so such output cannot be captured from inside a PowerShell session.[1]

However, an outside caller of PowerShell's CLI[2], such as cmd.exe in your case, does receive tracing output via stdout (the standard output stream)[3], so you can use cmd.exe's redirection to capture everything in a file and print it to the console afterwards.

A simplified example (from cmd.exe):

C:>powershell -c "Set-PSDebug -Trace 1; Write-Host 'Hello, World!'" > output.txt & type output.txt

DEBUG:    1+ Set-PSDebug -Trace 1;  >>>> Write-Host 'Hello, World!'
Hello, World!

[1] Perhaps surprisingly, despite the word "Debug" in the cmdlet name, tracing output does not go through stream number 5, the debugging stream, the way that Write-Debug output does.

[2] Note that you can use this technique of calling the CLI, invariably as a child process, from inside an existing PowerShell session as well, in which case that existing session acts as the outside caller. However, note that passing the command to execute via a script block ({ ... }), which is normally preferable, would not work in this case, because a script block-based invocation uses PowerShell's remoting infrastructure behind the scenes, which preserves the PowerShell-specific output streams (and also type fidelity, with limitations), so that the tracing output again goes straight to the console.

[3] Perhaps surprisingly, all of PowerShell's output streams - as well as to-console-only output such as produced by tracing - are by default mapped to an outside caller's stdout stream - including errors. While you can at least separate out errors on demand via a stderr redirection - 2> - on the caller side, all remaining streams are invariably sent to stdout - see the bottom section of this answer and GitHub issue #7989 for more information.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...