在不启用 -Verbose 的情况下捕获详细流

Capture verbose stream without enabling -Verbose

也许在 PowerShell 中无法做到这一点。

如果我有文件verboseTest.ps1

[CmdletBinding()]    # CmdletBinding attribute enables -verbose flag
Param()
Write-Verbose 'verbose test'

如果我调用 .\verboseTest.ps1,我什么也没看到。

如果我调用 .\verboseTest.ps1 -Verbose 我会看到输出。

VERBOSE: verbose test outer

符合预期。

但是如果我打电话给 .\verboseTest.ps1 4>&1 我不会。详细流丢失。

现在,Info 的行为完全不同了。

我有文件 infoTest.ps1,它运行正常。

[CmdletBinding()]    # Add CmdletBinding attribute
Param()
Write-Information 'info test outer'

如果我调用 .\infoTest.ps1,我什么也没看到。

如果我调用 .\infoTest.ps1 -InformationAction 'Continue',它类似于 -Verbose 标志,它会成功并向控制台输出 info test outer

如果我调用 .\infoTest.ps1 6>&1 也会 输出 info test outer 到控制台!因此,"information" 流的行为与 "verbose" 流完全不同。

信息流的行为是有道理的。写入信息命令写入流,我可以根据需要重定向或查看它。 "verbose" 没有!我必须启用在输出中显示它才能重定向它吗?难道我做错了什么?这有什么意义?

是否启用详细首选项以重定向输出?如果是这样,我可以在方法内部执行此操作还是在全局会话范围内更改它?

不幸的是,详细流(流编号 4)在未明确打开时不仅 静默,而且 没有数据写入.

Write-Verbose语句有效no-ops[1],除非-Verbose 被传递或首选项变量 $VerbosePreference 设置为 Continue.


在 PowerShell 的 silent-by-default 输出流中 - 详细 (4)、调试 (5) 和信息 (6) - 信息流是唯一的例外:Write-Information 语句 总是 写入它,无论它是否恰好被静音。


将首选项变量 $VerbosePreference 设置为 Continue 为当前作用域和任何子作用域中的所有命令打开详细输出 - 但是有一个 重要异常:

模块中实现的高级功能只看到一个全局实例从脚本调用时 $VerbosePreference;相比之下,二进制 cmdlets 受影响。 this GitHub issue.

中讨论了这种非常有问题的行为

您可以解决该问题,方法如下:

# Create a script-local copy of the global parameter-defaults
# hashtable.
# Note: If you want to clear the global presets, call .Clear()
#       after cloning.
$PSDefaultParameterValues = $PSDefaultParameterValues.Clone()

# Preset the -Verbose switch for all commands that support it.
$PSDefaultParameterValues['*:Verbose'] = $true

# ... call commands, which will behave as if -Verbose had been passed.

[1] 然而,该 cmdlet 仍被 调用 ,这意味着您传递给它的参数被评估,因此假设仍然可能静默 Write-Verbose 调用会产生副作用,例如将可扩展字符串作为包含具有副作用的子表达式 ($(...)) 的消息传递时。