PowerShell Tee-Object 不捕获文件中的调试行

PowerShell Tee-Object not capturing debug lines in file

我有一个 运行 自动化的 PowerShell 脚本,所以我需要将脚本的输出捕获到一个文件中,但我也想捕获 运行 的命令],为输出提供一些上下文(我会在 Linux shell 脚本中使用 set -x)。不过,我不知道如何将这些命令捕获到 Windows 中的输出文件中;非常感谢任何帮助!

# script.ps1

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

我如何调用脚本(从 cmd):

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

终端输出:

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

output.txt 文件内容:

Hello, World!

您可以看到输出文件缺少终端中显示的调试行。 理想情况下,我希望调试行只在输出文件中(而不是终端输出),但是在两个地方都有调试行也很好。

请注意,PowerShell 5.1 是我安装的版本。

不幸的是,PowerShell 的 tracing 输出 (通过 Set-PSDebug) operates outside PowerShell's system of output streams 激活,因此无法捕获此类输出 内部一个PowerShell会话。[1]

然而,一个外部调用者PowerShell's CLI[2],例如cmd.exe 在你的例子中,确实通过stdout(标准输出流)[3]接收跟踪输出,所以你可以使用 cmd.exe 的重定向来捕获文件中的所有内容,然后将其打印到控制台。

一个简化的例子(来自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] 也许令人惊讶的是,尽管 cmdlet 名称中包含“Debug”一词,跟踪输出确实 通过流编号5,调试流,Write-Debug 输出的方式。

[2] 请注意,您也可以从现有的 PowerShell 会话内部使用这种调用 CLI 的技术,总是作为 子进程 ,在这种情况下,现有会话充当外部调用者。但是,请注意,通过 script block ({ ... }) 传递要执行的命令通常更可取,但在这种情况下 不会 起作用,因为脚本块-based 调用在后台使用 PowerShell 的远程处理基础设施,它保留了 PowerShell 特定的输出流(以及类型保真度,但有限制),以便跟踪输出再次直接进入控制台。

[3] 也许令人惊讶的是,all PowerShell 的输出流 - 以及仅控制台输出,例如通过跟踪生成的输出 - 默认情况下映射到外部调用者的 stdout 流 - 包括错误。虽然您至少可以通过 stderr 重定向 on demand 分离出错误 - 2> - 在调用方,所有剩余的流都是总是发送到标准输出 - 请参阅 this answer and GitHub issue #7989 的底部部分以获取更多信息。