我有一个应用程序,允许您运行用户提供的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实例仅存在很短的时间 - 在执行之前没有长时间运行的过程来手动附加到并设置断点。
答案 0 :(得分:0)
从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
。