{"id":75451,"date":"2015-11-26T00:01:00","date_gmt":"2015-11-26T00:01:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2015\/11\/26\/beginning-use-of-powershell-runspaces-part-1\/"},"modified":"2019-07-29T15:18:02","modified_gmt":"2019-07-29T23:18:02","slug":"beginning-use-of-powershell-runspaces-part-1","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/beginning-use-of-powershell-runspaces-part-1\/","title":{"rendered":"Beginning Use of PowerShell Runspaces: Part 1"},"content":{"rendered":"<p><b style=\"font-size: 12px;\">Summary<\/b><span style=\"font-size: 12px;\">: Boe Prox presents some tips about beginning use with runspaces.<\/span><\/p>\n<p>Honorary Scripting Guy and Cloud and Datacenter Management MVP, Boe Prox, here today filling in for my good friend, The Scripting Guy.<\/p>\n<p><b>Note<\/b>\u00a0\u00a0\u00a0This is a four-part series that includes the following posts:<\/p>\n<ul>\n<li><a href=\"https:\/\/devblogs.microsoft.com\/scripting\/beginning-use-of-powershell-runspaces\" target=\"_blank\" rel=\"noopener noreferrer\">Beginning Use of PowerShell Runspaces: Part 1<\/a>\u00a0\u00a0\u00a0Begin use with runspaces.<\/li>\n<li><a href=\"https:\/\/devblogs.microsoft.com\/scripting\/beginning-use-of-powershell-runspaces-part-2\/\" target=\"_blank\" rel=\"noopener noreferrer\">Beginning Use of PowerShell Runspaces: Part 2<\/a>\u00a0\u00a0\u00a0Begin use with runspaces.<\/li>\n<li><a href=\"https:\/\/devblogs.microsoft.com\/scripting\/beginning-use-of-powershell-runspaces-part-3\" target=\"_blank\" rel=\"noopener noreferrer\">Beginning Use of PowerShell Runspaces: Part 3<\/a>\u00a0\u00a0Use runspace pools for multithreading.<\/li>\n<li><a href=\"https:\/\/devblogs.microsoft.com\/scripting\/weekend-scripter-a-look-at-the-poshrsjob-module\/\" target=\"_blank\" rel=\"noopener noreferrer\">A Look at the PoshRSJob Module<\/a>\u00a0\u00a0\u00a0Learn about a module for working with runspaces.<\/li>\n<\/ul>\n<p>Let&#8217;s say you are working in PowerShell and you want to kick off something to run in the background while you are working on some other things in the console. You would usually use something related to PSJobs, such as the <b>*-Job<\/b> cmdlets. Or you might use the <b>\u2013Asjob<\/b> parameter that you see in some cmdlets, such as <b>Get-WMIObject<\/b>.<\/p>\n<p>The main complaint in some of these efforts is that this causes another PowerShell process to be created and loaded with all of the format and type files, creating the PSDrives and such. This can take up a lot of resources depending on how many jobs you plan to run.<\/p>\n<p>Using runspaces is a great alternative to get around this issue. Runspaces create a new thread on the existing process, and you can simply add what you need to it and send it off running. The downside is the level of effort that is required to create the runspace and the PowerShell instance to run it. Additionally, you have to manage the whole process by kicking off the instance and monitoring it for completion. Then you need to retrieve the information (if applicable) and tear down the runspace and PowerShell instance for disposal.<\/p>\n<p>Using the built-in jobs framework makes this easy because you simply run something like <b>Start-Job<\/b> and then <b>Receive-Job<\/b> to get the data. Everything else happens behind the scenes. My plan is to take difficulty that may appear with using runspaces and show you how quickly and simply you can kick off a command in a runspace and pull it back without breaking a sweat.<\/p>\n<p>To start off, I will make use of the <b>[powershell]<\/b> type accelerator and use the <b>Create()<\/b> method to quickly create the instance. From there, I&#8217;ll add a script block and kick off the instance. Note that this already has a runspace built-in, so I do not have to worry about creating a new runspace at this point.<\/p>\n<p style=\"margin-left: 30px;\">$PowerShell = [powershell]::Create()<\/p>\n<p style=\"margin-left: 30px;\">[void]$PowerShell.AddScript({<\/p>\n<p style=\"margin-left: 30px;\">\u00a0\u00a0\u00a0 Get-Date<\/p>\n<p style=\"margin-left: 30px;\">})<\/p>\n<p style=\"margin-left: 30px;\">$PowerShell.Invoke()<\/p>\n<p>The result of running this is simply the return of the current date and time. Also look at where I used <b>[void]<\/b> so that it doesn\u2019t pollute my pipeline or anywhere in the output. What you may not know is that this is no different than what would run if I typed <b>Get-Date<\/b> in my console\u2014which is not really useful if we want a way to run things in the background. Add a <b>Start-Sleep \u2013Seconds 10<\/b> in my example script block, and you will see what I mean.<\/p>\n<p>Before I jump into some better multithreading examples, I am going to show the same example, but this time I am creating a runspace to work with and adding it to the PowerShell instance.<\/p>\n<p style=\"margin-left: 30px;\">$Runspace = [runspacefactory]::CreateRunspace()<\/p>\n<p style=\"margin-left: 30px;\">$PowerShell = [powershell]::Create()<\/p>\n<p style=\"margin-left: 30px;\">$PowerShell.runspace = $Runspace<\/p>\n<p style=\"margin-left: 30px;\">$Runspace.Open()<\/p>\n<p style=\"margin-left: 30px;\">[void]$PowerShell.AddScript({<\/p>\n<p style=\"margin-left: 30px;\">\u00a0\u00a0\u00a0 Get-Date<\/p>\n<p style=\"margin-left: 30px;\">})<\/p>\n<p style=\"margin-left: 30px;\">$PowerShell.Invoke()<\/p>\n<p>I need a better way to run a command in the background so the console can be open to do other things. Instead of using <b>Invoke()<\/b> to kick off our commands, I will instead use <b>BeginInvoke()<\/b>. This will give back an <b>async<\/b> object, which can be used to monitor the state of our currently running background command.<\/p>\n<p>Assuming that everything works out, we will eventually see that the background command has ended and I am free to retrieve the output and dispose of the PowerShell instance (so I do not have the possibility of memory leaks or something else).<\/p>\n<p>First things first. Let\u2019s kick off a background command and get back the object so we can track it.<\/p>\n<p style=\"margin-left: 30px;\">$Runspace = [runspacefactory]::CreateRunspace()<\/p>\n<p style=\"margin-left: 30px;\">$PowerShell = [powershell]::Create()<\/p>\n<p style=\"margin-left: 30px;\">$PowerShell.runspace = $Runspace<\/p>\n<p style=\"margin-left: 30px;\">$Runspace.Open()<\/p>\n<p style=\"margin-left: 30px;\">[void]$PowerShell.AddScript({<\/p>\n<p style=\"margin-left: 30px;\">\u00a0\u00a0\u00a0 Get-Date<\/p>\n<p style=\"margin-left: 30px;\">\u00a0\u00a0\u00a0 Start-Sleep -Seconds 10<\/p>\n<p style=\"margin-left: 30px;\">})<\/p>\n<p style=\"margin-left: 30px;\">$AsyncObject = $PowerShell.BeginInvoke()<\/p>\n<p>We can now inspect our Async object and view its status to see how things are going.<\/p>\n<p style=\"margin-left: 30px;\">$AsyncObject<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/1_PowerShellRunspace.png\"><img decoding=\"async\" title=\"Image of command output\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/1_PowerShellRunspace.png\" alt=\"Image of command output\" \/><\/a><\/p>\n<p>Based on the <b>IsCompleted<\/b> property, the command is currently running in the background, so I need to wait a little bit longer and then check again. When it shows <b>True<\/b>, I can begin processing the data and tearing down the instance.<\/p>\n<p>Let\u2019s assume that this has finally completed, and now I need to get the output. First I need to use the <b>async<\/b> object that was saved as the key to unlock the door on the PowerShell instance when I call <b>EndInvoke()<\/b>. As soon as I do this, the output is displayed. It is a good idea to save the output for future use.<\/p>\n<p>$Data = $PowerShell.EndInvoke($AsyncObject)<\/p>\n<p>Next up is to clean up by properly disposing of the instance. Nothing too crazy, but it is definitely necessary to ensure that I do not set myself up for disaster by having resource issues.<\/p>\n<p>$PowerShell.Dispose()<\/p>\n<p>And that is it for today and beginning with PowerShell runspaces. Tomorrow, I&#8217;ll build on what we learned by incorporating parameters and arguments into runspaces.<\/p>\n<p>I invite you to follow the Scripting Guy on\u00a0<a href=\"http:\/\/bit.ly\/scriptingguystwitter\" target=\"_blank\" rel=\"noopener noreferrer\">Twitter<\/a>\u00a0and\u00a0<a href=\"http:\/\/bit.ly\/scriptingguysfacebook\" target=\"_blank\" rel=\"noopener noreferrer\">Facebook<\/a>. If you have any questions, send email to the Scripting Guy at\u00a0<a href=\"mailto:scripter@microsoft.com\" target=\"_blank\" rel=\"noopener noreferrer\">scripter@microsoft.com<\/a>, or post your questions on the\u00a0<a href=\"http:\/\/bit.ly\/scriptingforum\" target=\"_blank\" rel=\"noopener noreferrer\">Official Scripting Guys Forum<\/a>. Until then, see ya!<\/p>\n<p><b>Boe Prox<\/b>, Windows PowerShell MVP and Honorary Scripting Guy<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Summary: Boe Prox presents some tips about beginning use with runspaces. Honorary Scripting Guy and Cloud and Datacenter Management MVP, Boe Prox, here today filling in for my good friend, The Scripting Guy. Note\u00a0\u00a0\u00a0This is a four-part series that includes the following posts: Beginning Use of PowerShell Runspaces: Part 1\u00a0\u00a0\u00a0Begin use with runspaces. Beginning Use [&hellip;]<\/p>\n","protected":false},"author":596,"featured_media":87096,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[162,56,650,3,45],"class_list":["post-75451","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-boe-prox","tag-guest-blogger","tag-runspace","tag-scripting-guy","tag-windows-powershell"],"acf":[],"blog_post_summary":"<p>Summary: Boe Prox presents some tips about beginning use with runspaces. Honorary Scripting Guy and Cloud and Datacenter Management MVP, Boe Prox, here today filling in for my good friend, The Scripting Guy. Note\u00a0\u00a0\u00a0This is a four-part series that includes the following posts: Beginning Use of PowerShell Runspaces: Part 1\u00a0\u00a0\u00a0Begin use with runspaces. Beginning Use [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/75451","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/users\/596"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/comments?post=75451"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/75451\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media\/87096"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media?parent=75451"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=75451"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=75451"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}