{"id":11211,"date":"2015-09-08T14:05:00","date_gmt":"2015-09-08T14:05:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/powershell\/2015\/09\/08\/powershell-runspace-debugging-part-1\/"},"modified":"2024-02-28T13:16:24","modified_gmt":"2024-02-28T21:16:24","slug":"powershell-runspace-debugging-part-1","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/powershell\/powershell-runspace-debugging-part-1\/","title":{"rendered":"PowerShell Runspace Debugging:  Part 1"},"content":{"rendered":"<p>This is the fourth in a series of blogs discussing the new PowerShell 5.0 script debugging features.\u00a0 These new features are available through the PowerShell 5.0 preview, which is part of the WMF (Windows Management Foundation) 5.0 preview that you can get from <a href=\"http:\/\/blogs.msdn.com\/b\/powershell\/archive\/2015\/08\/31\/windows-management-framework-5-0-production-preview-is-now-available.aspx\">HERE<\/a>.<\/p>\n<p>In my last article I talked about the Debug-Job command.\u00a0 In this blog I will discuss Runspace debugging which is similar to debugging a job.\u00a0 Runspace debugging is an advanced activity, but is incredibly useful in the right circumstances.<\/p>\n<p>A Runspace is an instance of the PowerShell engine within a process.\u00a0 It defines the context in which a PowerShell command or script runs and contains state that is specific to your PowerShell session, including variables and functions that you define, modules that you load, etc.\u00a0 Normally your ISE or console has a single (default) Runspace, but you can have more than one.\u00a0 Multiple Runspaces let you run scripts concurrently; this has been true since PowerShell version 1 as can be seen in this example: <a href=\"https:\/\/jtruher3.wordpress.com\/2006\/08\/30\/background-jobs-and-powershell\/\">Jim Truher\u2019s Blog (2006)<\/a>.<\/p>\n<p>The PowerShell console and ISE (Integrated Script Environment) create a default Runspace for you.\u00a0 You can see all Runspaces by using the new Get-Runspace cmdlet.<\/p>\n<h2>Get-Runspace<\/h2>\n<p><span style=\"font-family: 'Calibri','sans-serif'; font-size: 11pt;\">Get-Runspace lists all Runspaces in the current process (and AppDomain, but I\u2019ll discuss that in a later blog).<\/span><\/p>\n<p><span style=\"font-family: courier new,courier;\">PS C:\\&gt; Get-Runspace<\/span><\/p>\n<p><span style=\"font-family: courier new,courier;\">Id Name\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ComputerName\u00a0\u00a0\u00a0 Type\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 State\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Availability\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-family: courier new,courier;\">&#8212; &#8212;-\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &#8212;&#8212;&#8212;&#8212;\u00a0\u00a0\u00a0 &#8212;-\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &#8212;&#8211;\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &#8212;&#8212;&#8212;&#8212;\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-family: courier new,courier;\">\u00a01\u00a0Runspace1\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 localhost\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Local\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Opened\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Busy\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><\/p>\n<h2>Debug-Runspace<\/h2>\n<p>The PowerShell console or ISE script debugger only works on the default Runspace.\u00a0 So how do you debug script in alternate Runspaces?<\/p>\n<p>Debug-Runspace lets you connect the debugger to another Runspace.<\/p>\n<p>&nbsp;<\/p>\n<h2>Example: Creating and debugging alternate Runspaces<\/h2>\n<p>In this example I will show you how to create another Runspace in your PowerShell session, run a script file concurrently in it, and then debug that running script with the ISE debugger.\u00a0 You create a Runspace using the PowerShell API.\u00a0 Jim Truher\u2019s blog shown above also uses the API to create and use Runspaces.\u00a0 What I will show here is the minimum needed.\u00a0 But if you would like more information take a look at these two blogs:<\/p>\n<p><a href=\"http:\/\/blogs.msdn.com\/b\/powershell\/archive\/2013\/10\/01\/paap-windows-powershell-as-a-platform-part-1.aspx\">http:\/\/blogs.msdn.com\/b\/powershell\/archive\/2013\/10\/01\/paap-windows-powershell-as-a-platform-part-1.aspx<\/a><\/p>\n<p><a href=\"http:\/\/blogs.msdn.com\/b\/powershell\/archive\/2013\/10\/31\/paap-windows-powershell-as-a-platform-part-2.aspx\">http:\/\/blogs.msdn.com\/b\/powershell\/archive\/2013\/10\/31\/paap-windows-powershell-as-a-platform-part-2.aspx<\/a><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"font-family: courier new,courier;\">PS C:\\&gt; $rs = [runspacefactory]::CreateRunspace()<\/span><\/p>\n<p><span style=\"font-family: courier new,courier;\">PS C:\\&gt; $rs.Name = &#8220;MyRunspace&#8221;<\/span><\/p>\n<p><span style=\"font-family: courier new,courier;\">PS C:\\&gt; $rs.Open()<\/span><\/p>\n<p><span style=\"font-family: courier new,courier;\">PS C:\\&gt; Get-Runspace<\/span><\/p>\n<p><span style=\"font-family: courier new,courier;\">Id Name\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ComputerName\u00a0\u00a0\u00a0 Type\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 State\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Availability\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-family: courier new,courier;\">&#8212; &#8212;-\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &#8212;&#8212;&#8212;&#8212;\u00a0\u00a0\u00a0 &#8212;-\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &#8212;&#8211;\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &#8212;&#8212;&#8212;&#8212;\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-family: courier new,courier;\">\u00a01\u00a0Runspace1\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 localhost\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Local\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Opened\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Busy<\/span><\/p>\n<p><span style=\"font-family: courier new,courier;\">\u00a02 MyRunspace\u00a0\u00a0\u00a0\u00a0\u00a0 localhost\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Local\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Opened\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Available\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"font-family: courier new,courier;\">PS C:\\&gt; $ps = [powershell]::Create()<\/span><\/p>\n<p><span style=\"font-family: courier new,courier;\">PS C:\\&gt; $ps.Runspace = $rs<\/span><\/p>\n<p><span style=\"font-family: courier new,courier;\">PS C:\\&gt; $ps.AddScript(&#8216;C:\\TestScript.ps1&#8217;) &gt; $null<\/span><\/p>\n<p><span style=\"font-family: courier new,courier;\">PS C:\\&gt; $async = $ps.BeginInvoke()<\/span><\/p>\n<p><span style=\"font-family: courier new,courier;\">PS C:\\&gt; Get-Runspace<\/span><\/p>\n<p><span style=\"font-family: courier new,courier;\">Id Name\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ComputerName\u00a0\u00a0\u00a0 Type\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 State\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Availability\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-family: courier new,courier;\">&#8212; &#8212;-\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &#8212;&#8212;&#8212;&#8212;\u00a0\u00a0\u00a0 &#8212;-\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &#8212;&#8211;\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &#8212;&#8212;&#8212;&#8212;\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-family: courier new,courier;\">\u00a01\u00a0Runspace1\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 localhost\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Local\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Opened\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Busy<\/span><\/p>\n<p><span style=\"font-family: courier new,courier;\">\u00a02 MyRunspace\u00a0\u00a0\u00a0\u00a0\u00a0 localhost\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Local\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Opened\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Busy\u00a0\u00a0\u00a0<\/span><\/p>\n<p>&nbsp;<\/p>\n<p>When we now run Get-Runspace we see that the MyRunspace Availability is \u201cbusy\u201d, meaning that it is running the test script file.<\/p>\n<p>Finally we debug this running script by using Debug-Runspace to attach the ISE debugger to its Runspace.<\/p>\n<p><span style=\"font-family: courier new,courier;\">PS C:\\&gt; Debug-Runspace MyRunspace<\/span><\/p>\n<p><span style=\"font-family: courier new,courier;\">Debugging Runspace: MyRunspace<\/span><\/p>\n<p><span style=\"font-family: courier new,courier;\">To end the debugging session type the &#8216;Detach&#8217; command at the debugger prompt, or type &#8216;Ctrl+C&#8217; otherwise.<\/span><\/p>\n<p><span style=\"font-family: courier new,courier;\">[DBG]: [Process:13332]: [MyRunspace]: PS C:\\&gt;&gt;<\/span><\/p>\n<p>Notice the message you get when running Debug-Runspace.\u00a0 Debug-Runspace attaches your PowerShell console or ISE script debugger to the specified Runspace.\u00a0 If that Runspace is idle and not running any script then Debug-Runspace waits for script to start running at which time it will stop the script in the debugger.\u00a0 You can quit the Debug-Runspace command and detach the debugger by typing Ctrl+C.<\/p>\n<p>Since the Runspace is busy running script, attaching the debugger also stops the script inside the debugger in step mode.\u00a0 The TestScript.ps1 script file is opened in the ISE and you can now debug the script just as if it was running in the ISE.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/powershell\/wp-content\/uploads\/sites\/30\/2015\/09\/2570.ISE_Debugging.png\"><img decoding=\"async\" class=\"alignnone size-full wp-image-20457\" src=\"https:\/\/devblogs.microsoft.com\/powershell\/wp-content\/uploads\/sites\/30\/2015\/09\/2570.ISE_Debugging.png\" alt=\"Image 2570 ISE Debugging\" width=\"944\" height=\"380\" srcset=\"https:\/\/devblogs.microsoft.com\/powershell\/wp-content\/uploads\/sites\/30\/2015\/09\/2570.ISE_Debugging.png 944w, https:\/\/devblogs.microsoft.com\/powershell\/wp-content\/uploads\/sites\/30\/2015\/09\/2570.ISE_Debugging-300x121.png 300w, https:\/\/devblogs.microsoft.com\/powershell\/wp-content\/uploads\/sites\/30\/2015\/09\/2570.ISE_Debugging-768x309.png 768w\" sizes=\"(max-width: 944px) 100vw, 944px\" \/><\/a><\/p>\n<p>When you are done debugging the script you can use the debugger command \u2018quit\u2019 to stop the script and detach the debugger.\u00a0 Or you can use the \u2018detach\u2019 command to just detach the debugger and let the script continue to run.\u00a0 I have chosen to detach the debugger.<\/p>\n<p><span style=\"font-family: courier new,courier;\">[DBG]: [Process:13332]: [MyRunspace]: PS C:\\&gt;&gt; detach<\/span><\/p>\n<p><span style=\"font-family: courier new,courier;\">PS C:\\&gt;<\/span><\/p>\n<p>&nbsp;<\/p>\n<p>In this article I showed you how to view and debug Runspaces.\u00a0 But how would you view and debug a Runspace running in a different process?\u00a0 And what if the Runspace you want to debug is running on a different machine?\u00a0 In my next blog I will show you how to do this using the new Enter-PSHostProcess cmdlet.<\/p>\n<p>&nbsp;<\/p>\n<p>Paul Higinbotham [MSFT]<\/p>\n<p>Senior Software\u00a0Engineer<\/p>\n<p>PowerShell Core<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This is the fourth in a series of blogs discussing the new PowerShell 5.0 script debugging features.\u00a0 These new features are available through the PowerShell 5.0 preview, which is part of the WMF (Windows Management Foundation) 5.0 preview that you can get from HERE. In my last article I talked about the Debug-Job command.\u00a0 In [&hellip;]<\/p>\n","protected":false},"author":609,"featured_media":13641,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[7],"class_list":["post-11211","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-powershell","tag-powershell-5-0"],"acf":[],"blog_post_summary":"<p>This is the fourth in a series of blogs discussing the new PowerShell 5.0 script debugging features.\u00a0 These new features are available through the PowerShell 5.0 preview, which is part of the WMF (Windows Management Foundation) 5.0 preview that you can get from HERE. In my last article I talked about the Debug-Job command.\u00a0 In [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/posts\/11211","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/users\/609"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/comments?post=11211"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/posts\/11211\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/media\/13641"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/media?parent=11211"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/categories?post=11211"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/tags?post=11211"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}