如何暂停powershell脚本,直到调试器附加

Posted

技术标签:

【中文标题】如何暂停powershell脚本,直到调试器附加【英文标题】:How to pause a powershell script until a debugger attaches 【发布时间】:2017-03-11 03:55:02 【问题描述】:

我有一个允许您运行用户提供的 PowerShell 脚本的应用程序。我想在脚本顶部注入一些代码以在第一行暂停正在运行的脚本,并等待调试器(即 PowerShell ISE)附加。

我想要实现的一个很好的例子是 DSC 如何暂停并等待您附加:

PS C:\> Enable-DscDebug -BreakAll
PS C:\> Start-DscConfiguration .\temp\DSCTestClass -wait -force
WARNING: [DEV-14257-44]: [DSCEngine] Warning LCM is in Debug 'ResourceScriptBreakAll' mode. Resource script processing will be stopped to wait for PowerShe1l script debugger to attach.
WARNING: [DEV-14257-44]: [[FileResource]file] Resource is waiting for PowerShell script debugger to attach. Use the following commands to begin debugging this resource script:
Enter-PSSession -ComputerName DEV-14257-44 -Credential <credentials>
Enter-PSHostProcess -Id 596 -AppDomainName DscPsPluginWkr_AppDomain
Debug-Runspace -Id 4

(这个例子来自https://blogs.msdn.microsoft.com/powershell/2016/03/14/debugging-powershell-dsc-class-resources/)

不幸的是,当我尝试设置类似的等待时,powershell.exe 会自动启动命令行调试器:

给定文件test.ps1

set-psbreakpoint -script "test.ps1" -line 4
write-host "pid is $pid"
write-host "Pausing for debugger to attach"
write-host "Paused waiting for debugger to attach"

当我运行它时(即使在-noninteractive 模式下),它会启动命令行调试器:

PS C:\temp\PowershellDebugging> powershell -file .\test.ps1 -noninteractive

  ID Script                           Line Command                          Variable                        Action
  -- ------                           ---- -------                          --------                        ------
   0 test.ps1                         4
pid is 13228
Pausing for debugger to attach
Entering debug mode. Use h or ? for help.

Hit Line breakpoint on 'C:\temp\PowershellDebugging\test.ps1:6'

At C:\temp\PowershellDebugging\test.ps1:6 char:1
+ write-host "Paused waiting for debugger to attach"
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[DBG]: PS C:\temp\PowershellDebugging>

如何在不启动命令行调试器的情况下让 PowerShell 中断/暂停执行?

编辑:

正在执行的脚本只存在很短的时间(它被写入磁盘,执行,然后清理)。此外,运行它的 powershell.exe 实例只存在很短的时间 - 没有长时间运行的进程可以在执行之前手动附加并设置断点。

【问题讨论】:

您是否尝试过 PowerShell 5 中的 Wait-Debugger? msdn.microsoft.com/en-us/powershell/reference/5.1/… 不幸的是,它以同样的方式直接进入调试器。 wait-debugger 似乎是为在 powershell 作业中使用而设计的。 尝试在循环中评估 Debugger.IsAttached? msdn.microsoft.com/en-us/library/… 不幸的是,它不起作用 - 它没有检测到调试器附加。一旦调试器附加,它就会中断循环。看起来它相当于做while($true) write-host 'looping' 并附加到它。 【参考方案1】:

在得到 PowerShell 团队的帮助(谢谢!)后,发现关键是使用 New-RunSpace。通常,如果您只是执行一个脚本,它将在默认的 RunSpace 中运行,并且已经附加了内置的 PowerShell 调试器。

以下演示如何使用它:

# create a fake script that simulates the user provided scrip 
@'
  Write-Output "Starting Test"
  1..20 | foreach 
     Write-Output "I Love PowerShell!"
  
  Write-Output "Test Complete"
'@ | Set-Content -Path c:\temp\Test.ps1

# create a launcher script
@'
  Write-Output "Process Id: $pid"
  $ps = [powershell]::Create([System.Management.Automation.RunspaceMode]::NewRunspace)
  Write-Output "Runspace Id: $($ps.Runspace.Id)"
  $ps.AddScript(‘Wait-Debugger; C:\temp\Test.ps1’).Invoke()
'@ | Set-Content -Path c:\temp\LaunchTestInNewRunspace.ps1

# run the launch script
PS C:\> powershell -File c:\temp\LaunchTestInNewRunspace.ps1
Process Id: 14288
Runspace Id: 2

在另一个窗口中:

# in another window
PS C:\> Enter-PSHostProcess -Id 14288
[Process:14288]: PS C:\> Debug-RunSpace -Id 2
Debugging Runspace: Runspace2
To end the debugging session type the 'Detach' command at the debugger 
prompt, or type 'Ctrl+C' otherwise.

Entering debug mode. Use h or ? for help.

At line:1 char:16
+ Wait-Debugger; C:\temp\Test.ps1
+                ~~~~~~~~~~~~~~~~

这会进入调试器,准备单步执行Test.ps1

【讨论】:

以上是关于如何暂停powershell脚本,直到调试器附加的主要内容,如果未能解决你的问题,请参考以下文章

Powershell表单 - 使用按钮暂停循环

如何暂停 R 脚本,直到下载文件?

暂停进程以留出时间让调试器附加

如何使用 PowerShell 或 python 脚本读取、编辑或附加存储在 Azure Blob 存储中的 Excel 文件(列和行)

powershell 暂停脚本

我可以在方法条目上暂停 Java 运行时以便有时间通过​​调试器或探查器附加吗?