有没有办法进入调试器的错误? [英] Is there a way to enter the debugger on an error?
问题描述
有没有办法进入PowerShell调试器以回应错误? ErrorAction
参数有几个值,但我看不到任何类似 Debug
的内容。我想要的是打开调试器,就像打开它一样,如果我设置了一个断点,但只有当发生错误(从,例如写入错误
)。 / p>
编辑
我应该澄清一点:我主要是一个C#开发人员,对PowerShell来说有些新意,我期待的是行为类似于Visual Studio调试器为您提供未处理的异常。 PowerShell命令看起来更常见的是抛出异常,而自定义脚本似乎主要使用Write-Error。我不认为我特别关心两者之间的区别,但我想处理两者。
Trevor Sullivan的答案在下面提到您可以使用 Set-PSBreakpoint - 命令写错误-Action {break; };
似乎很好地抓住这些情况。尽管如此,我发现在很多情况下,它实际上是一个命令,抛出一个我想打破的异常。如果您设置 $ ErrorActionPreference =stop
,那么Roman Kuzmin的回答似乎有效,但是我有这个问题,我无法通过该程序,似乎突破了位置并结束脚本。如果 $ ErrorActionPreference =continue
它对我来说不起作用。陷阱通常似乎有一个类似的问题,它们从任何嵌套的范围中分离出来,这是不需要的。
课程。您可以使用 Set-PSBreakpoint
cmdlet在PowerShell中创建条件断点。请考虑以下代码。将其另存为脚本文件,然后执行。有一些内行评论可以帮助您了解发生了什么。
请记住有三种不同类型的断点:
- 行
- 变量
- 命令
命令断点
此代码示例正在使用命令断点类型,因为我只告诉它只设置断点在 Get-WmiObject
命令。您可以选择指定一个特定的行号或一个变量断点类型。您可以使用 -Action
参数来指定要设置断点的条件。您必须在 -Action
ScriptBlock
break >以指示调试器暂停执行PowerShell脚本。
#1.将$错误重置为$ null
$ WmiError = $ null;
#2.清理任何现有的断点
Get-PSBreakpoint | Remove-PSBreakpoint;
#3.当$ WmiError变量不为$ null
时,设置断点,但仅限于Get-WmiObject命令Set-PSBreakpoint -Command Get-WmiObject -Action {if($ WmiError ){break; }};
#4.失败Get-WmiObject命令
Get-WmiObject - 类Win32_NonExistentClass -ErrorVariable WmiError;
#5.成功的Get-WmiObject命令
#PowerShell在这里打破,因为:
# - 这是一个Get-WmiObject命令
# - $ WmiError变量是not null
Get-WmiObject -Class Win32_BIOS;
由于您提到使用 Write-Error
您可以在出现写入错误
的行上设置 PSBreakpoint
。这是一个如何做的例子:
Set-PSBreakpoint - 命令写错误 - };
很简单,对不对?
变量断点
此示例使用变量 PSBreakpoint
类型,但只有当变量的内容被修改时。您可以使用 -Mode
参数来确定在什么情况下,变量断点被击中:
- 阅读
- ReadWrite
- 写
代码:
#1.清理任何现有的断点
Get-PSBreakpoint | Remove-PSBreakpoint;
#2.在名为数据的变量上设置一个类型为variable的PSBreakpoint,但只有当它更改
Set-PSBreakpoint -Action {Write-Host -ForegroundColor Green - Object('$ data变量已更改!值为:{0}'-f $ Data);打破; }变量数据 - 模式写;
#3.这行上没有中断,因为我们没有更改变量
Write-Host -Object $ Data;
#4.执行在此行中暂停,因为我们更改变量
$ Data = 1;
线断点
ve查看变量和命令 PSBreakpoint
类型,最后一个要查看的断点类型是行断点。如果要复制/粘贴下面的代码,请保存并执行,您将看到代码在写入主机行(恰好是第9行)中断,但只有当
属性等于 $ Service
变量的名称 WinRM
。这就是 -Action
参数的 ScriptBlock
中的条件语句定义。
#1.清理任何现有的断点
Get-PSBreakpoint | Remove-PSBreakpoint;
#2.在#8行设置一个类型为line的PSBreakpoint,但只有$ Service变量的Name属性等于'winrm'
Set-PSBreakpoint -Action {if($ Service.Name -eq'winrm'){break; }} -Line 9 -Script $ MyInvocation.MyCommand.Path;
#3.获取Windows服务列表并对其进行迭代
foreach($ Service in(Get-WmiObject -Class Win32_Service)){
Write-Host -Object '服务名称是:{0}'-f $ Service.Name);
}
Is there a way to enter the PowerShell debugger in response to an error? The ErrorAction
parameter has several values but I don't see anything like Debug
. What I would like is to open the debugger like it would open if I had set a breakpoint, but only when an error occurs (from, say, Write-Error
).
Edit I should clarify a bit: I am primarily a C# developer and somewhat new to PowerShell, what I am expecting is behavior similar to what the Visual Studio debugger gives you for "unhandled exceptions". It appears that it is more common for PowerShell commands to throw exceptions, while custom scripts seem to mostly use Write-Error. I don't think I particularly care to distinguish between the two, but I would like to handle both.
Trevor Sullivan's answer below mentions that you can use Set-PSBreakpoint -Command Write-Error -Action { break; };
which appears to work well to catch those cases. Though, I am finding that in many cases it is actually a command throwing an exception that I would like to break on. Roman Kuzmin's answer appears to work if you set $ErrorActionPreference = "stop"
, however, I have the problem that I cannot step through the program, it seems to break out of that location and end the script. If $ErrorActionPreference = "continue"
it does not work for me. Traps in general seem to have a similar issue that they break out out of any nested scopes, which is not desired.
Of course. You can create conditional breakpoints in PowerShell, using the Set-PSBreakpoint
cmdlet. Consider the following code. Save it as a script file, and execute it. There are in-line comments to help you understand what's going on.
Keep in mind that there are three different types of breakpoints:
- Line
- Variable
- Command
Command Breakpoint
This code example is using the command breakpoint type, because I am telling it to only set breakpoints on Get-WmiObject
commands. You can alternately specify a specific line number or a variable breakpoint type. You use the -Action
parameter to specify the conditions under which you want the breakpoint to be set. You must use the break
keyword somewhere inside the -Action
ScriptBlock
in order to instruct the debugger to pause execution of the PowerShell script.
# 1. Reset $Error to $null
$WmiError = $null;
# 2. Clean up any existing breakpoints
Get-PSBreakpoint | Remove-PSBreakpoint;
# 3. Set breakpoint, but only on Get-WmiObject commands, when the $WmiError variable is not $null
Set-PSBreakpoint -Command Get-WmiObject -Action { if ($WmiError) { break; } };
# 4. Failed Get-WmiObject command
Get-WmiObject -Class Win32_NonExistentClass -ErrorVariable WmiError;
# 5. Successful Get-WmiObject command
# PowerShell breaks here, because:
# - It's a Get-WmiObject command
# - The $WmiError variable is not null
Get-WmiObject -Class Win32_BIOS;
Since you mentioned using Write-Error
, you could set a PSBreakpoint
on lines where Write-Error
appears. Here is an example of how to do that:
Set-PSBreakpoint -Command Write-Error -Action { break; };
Pretty easy, right?
Variable Breakpoint
This example uses the variable PSBreakpoint
type, but only when the variable's contents are modified. You can use the -Mode
parameter to determine under what conditions the variable breakpoint is hit:
- Read
- ReadWrite
- Write
Code:
# 1. Clean up any existing breakpoints
Get-PSBreakpoint | Remove-PSBreakpoint;
# 2. Set a PSBreakpoint of type "variable" on a variable named "Data," but only when it has changed
Set-PSBreakpoint -Action { Write-Host -ForegroundColor Green -Object ('The $Data variable has changed! Value is: {0}' -f $Data); break; } -Variable Data -Mode Write;
# 3. No break on this line, because we are not changing the variable
Write-Host -Object $Data;
# 4. Execution is paused on this line, because we change the variable
$Data = 1;
Line Breakpoint
Now that we've looked at the variable and command PSBreakpoint
types, the last type of breakpoint to explore is the line breakpoint. If you were to copy/paste the code below, save it, and execute it, you would see that the code breaks on the Write-Host line (which happens to be line 9), but only when the Name
property of the $Service
variable is equal to WinRM
. That is what the conditional statement in the -Action
parameter's ScriptBlock
defines.
# 1. Clean up any existing breakpoints
Get-PSBreakpoint | Remove-PSBreakpoint;
# 2. Set a PSBreakpoint of type "line" on line #8, but only if the $Service variable's Name property equals 'winrm'
Set-PSBreakpoint -Action { if ($Service.Name -eq 'winrm') { break; } } -Line 9 -Script $MyInvocation.MyCommand.Path;
# 3. Get a list of Windows Services and iterate over them
foreach ($Service in (Get-WmiObject -Class Win32_Service)) {
Write-Host -Object ('Service name is: {0}' -f $Service.Name);
}
这篇关于有没有办法进入调试器的错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!