用PowerShell如何让Write-Debug输出显示在控制台中?

28
我是一名学习PowerShell的人,之前使用Write-Host命令来检查新建PowerShell脚本文件中的变量赋值情况。后来我读了一篇文章,认为这样做不太好。

因此,在我的.ps1文件中,我将像这样的语句进行了替换:

Write-Host "Start"
Write-Host "End"

用这个:

Write-Debug "Start"
Write-Debug "End"

但是当我在Windows PowerShell ISE中运行保存的脚本时,控制台没有输出。我在调用脚本的语句后添加了-debug,像这样:

PS E:\trialrun> .\MyScript.ps1 -debug

但是,输出内容仍然没有被写入控制台。显然我在错误地使用Write-Debug。如何让调试输出写入控制台?


在脚本中将 Write-Debug "Start" 改为 Write-Debug "Start" -debug(而不是在调用脚本时尝试绑定它),然后对 End 也做同样的操作。否则,请查看此答案有关绑定参数的内容,例如 debug。 - LinkBerest
1
链接似乎已经损坏。 - Peter Mortensen
4个回答

47

tl;dr:

  • 运行 $DebugPreference = 'Continue' 开始查看 Write-Debug 调用的输出。

  • 完成后,使用 $DebugPreference = 'SilentlyContinue' 恢复首选项变量 $DebugPreference 的默认值。

  • 要仅为给定 cmdlet 或高级函数打开调试输出,请使用 -Debug 公共参数。

    • 注意事项:在 Windows PowerShell 中(但不再适用于 PowerShell [Core] v6+),这将为遇到的每个 Write-Debug 语句呈现交互式调试提示。

Write-Debug 语句的输出是否被打印由两种机制控制:

$DebugPreference 默认为 SilentlyContinue,这就解释了为什么默认情况下不会看到来自 Write-Debug 语句的任何输出。

当您使用通用参数-Debug时,您实际上只针对调用的命令设置了$DebugPreference 临时值,并且:

  • Windows PowerShell中,您会将其不可避免地设置为值Inquire,这不仅打印Write-Debug消息,还会在每个这样的语句处暂停以询问您如何继续进行

  • PowerShell [Core] v6+中,该值现在被(更明智地)设置为Continue

    • 要使自定义脚本或函数支持-Debug通用参数,它必须是一个高级函数,使用[CmdletBinding()]属性声明其param()块,如Mathias' answer所示。

由于在Windows PowerShell中,这种每次Write-Debug调用都提示的行为可能会干扰您的操作,$DebugPreference = 'Continue'可能是更好的方法。如上所述,在PowerShell [Core] v6+中不再存在此问题。

注意:如果您希望从高级函数或脚本内部区分调用者设置了$DebugPreference 作为偏好变量还是传递了通用参数-Debug(这将被转换为函数/脚本本地的$DebugPreference变量),请使用下面的语句:

$PSBoundParameters.ContainsKey('Debug')$true表示使用了-Debug选项。


官方文档参考:https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/write-debug

默认情况下,调试消息不会在控制台中显示,但您可以使用Debug参数或$DebugPreference变量来显示它们。


2
谢谢。这是一个很酷的方法。我不知道参数可以像这样查询键。相反,我实际上已经编写了一个 if ($DebugPreference -eq 'Inquire' ) 语句来检查,然后如果为真设置 $DebugPreference = 'Continue'。如果客户端总是有 PS6,那就更容易了。 - Blaisem

20

如果您想要支持常用参数(包括-Debug),则需要在脚本中添加CmdletBinding属性:

[CmdletBinding()]
param()

Write-Debug Start
Write-Debug End

我建议查看about_Functions_CmdletBindingAttribute帮助文件


2
这是一般情况下的好建议,但与其他常见参数(如-ErrorAction)不同,-Debug不允许您为隐含的命令范围$DebugPreference变量传递_特定值_,而是始终将其设置为Inquire,这意味着遇到每个Write-Debug语句都会_提示_,如果您只想要_打印_调试消息,则会产生干扰。 - mklement0

1
这对我来说很有效 - testscript.ps1:
param(
    [switch]$Debug = $false
)

if ( $Debug ) {
    $DebugPreference = "Continue"
}

Write-Debug "This is a test"

这样我就可以用以下方式运行我的脚本:
./testscript -Debug

如果我不想要输出,可以去掉-Debug

好答案。你可能需要查看一下在$PSBoundParameters.ContainsKey('Debug')上做一个if检查,因为如果最终转换为高级函数,这里的Debug开关将与Cmdletbinding()添加的开关冲突。 - undefined

0

如果您在每个模块函数的进程块中放置$DebugPreference = 'Continue',它将按预期工作。有点重复,但这比其他一些解决方案要容易得多。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接