{"id":105109,"date":"2025-02-03T09:58:00","date_gmt":"2025-02-03T09:58:00","guid":{"rendered":"https:\/\/www.red-gate.com\/simple-talk\/?p=105109"},"modified":"2025-02-03T14:12:35","modified_gmt":"2025-02-03T14:12:35","slug":"fun-with-powershell-asynchronous","status":"publish","type":"post","link":"https:\/\/www.red-gate.com\/simple-talk\/sysadmin\/powershell\/fun-with-powershell-asynchronous\/","title":{"rendered":"Fun with PowerShell Asynchronous"},"content":{"rendered":"<p>Imagine a candle that is lit and takes 1 hour to burn out. Now imagine one hundred candles. How many hours will it last? That depends. If they are lit simultaneously, it will take 1 hour.<\/p>\n<p>That is the basic idea of running in the background or asynchronously. Of course, the 100 candles can execute independently of one another, unlike if you try to run 100 processes on a computer with 2 cores.<\/p>\n<p>PowerShell has some ways to manage that, as PowerShell job \u2013 which we will see in this article \u2013 runspaces \u2013 needs to add programmable using .net.<\/p>\n<h2>PowerShell Jobs<\/h2>\n<p>PowerShell Jobs is a valuable tool that allows you to run commands or scripts in the background without interrupting the current session. It also provides a way to run processes asynchronously. This means you can start a job and then move on to other tasks while it is completed in the background. You can manage and control these jobs within your PowerShell session.<\/p>\n<p>PowerShell can concurrently execute scripts and commands using jobs. There are three job types that you can use to support concurrency.<\/p>\n<ul>\n<li><a href=\"https:\/\/learn.microsoft.com\/en-us\/powershell\/module\/microsoft.powershell.core\/about\/about_remote_jobs\">RemoteJob<\/a> \u2013 Used to run commands and scripts run on a remote session.<\/li>\n<li><a href=\"https:\/\/learn.microsoft.com\/en-us\/powershell\/module\/microsoft.powershell.core\/about\/about_jobs\">BackgroundJob<\/a> &#8211; Commands and scripts run in a separate process on the local machine.<\/li>\n<li><a href=\"https:\/\/learn.microsoft.com\/en-us\/powershell\/module\/microsoft.powershell.core\/about\/about_thread_jobs\">PSTaskJob\u00a0or\u00a0ThreadJob<\/a> &#8211; Commands and scripts executed in a separate thread within the same process on the local machine.<\/li>\n<\/ul>\n<p>In this article, I will focus on use <code>BackgroundJobs<\/code>, but there are similarities to each, other then the context in which they are executed.<\/p>\n<h2>Starting a job on the local computer<\/h2>\n<p>To create and start a job on the local computer, use the Star-Job cmdlet. It takes a variable called <em>the script block as<\/em> a parameter.<\/p>\n<p>What is a scriptblock?<\/p>\n<p>In PowerShell, a script block is a collection of statements or expressions that can be used as a single unit. The collection of instructions can be enclosed in braces ({}), defined as a function, or saved in a script file. A script block can return values and accept parameters and arguments.<\/p>\n<p>The following command starts a background job that runs a <code>Get-Service<\/code> cmdlet on the local computer.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"1344\" height=\"293\" class=\"wp-image-105110\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2025\/01\/a-screenshot-of-a-computer-screen-description-aut.png\" alt=\"A screenshot of a computer screen\n\nDescription automatically generated\" srcset=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2025\/01\/a-screenshot-of-a-computer-screen-description-aut.png 1344w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2025\/01\/a-screenshot-of-a-computer-screen-description-aut-300x65.png 300w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2025\/01\/a-screenshot-of-a-computer-screen-description-aut-1024x223.png 1024w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2025\/01\/a-screenshot-of-a-computer-screen-description-aut-768x167.png 768w\" sizes=\"auto, (max-width: 1344px) 100vw, 1344px\" \/><\/p>\n<p>As it runs in the background, <code>start-job<\/code> returns information about the job that was created, and you can continue your work in the session without interruption while the job runs.<\/p>\n<p>The information about the job is automatically shown as the <code>ID, Name<\/code> \u2013 if you don\u2019t name your job, it will create a name <code>JobX<\/code>&#8211; and more information about the job.<\/p>\n<h2>Getting the result of a job<\/h2>\n<p>The result does not appear immediately when you run a background job, as it works in another context. To get the result, you need to use <code>Receive-Job<\/code><em>. <\/em>As we saw in the start-job result, the job <code>ID<\/code> is 7, so we can use this <code>ID<\/code>.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"1340\" height=\"767\" class=\"wp-image-105111\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2025\/01\/a-screen-shot-of-a-computer-description-automatic.png\" alt=\"A screen shot of a computer\n\nDescription automatically generated\" srcset=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2025\/01\/a-screen-shot-of-a-computer-description-automatic.png 1340w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2025\/01\/a-screen-shot-of-a-computer-description-automatic-300x172.png 300w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2025\/01\/a-screen-shot-of-a-computer-description-automatic-1024x586.png 1024w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2025\/01\/a-screen-shot-of-a-computer-description-automatic-768x440.png 768w\" sizes=\"auto, (max-width: 1340px) 100vw, 1340px\" \/><\/p>\n<h2>Working with Receive-Job<\/h2>\n<p>If we try to rerun <code>Receive-Job<\/code>, it will not show anything.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"1341\" height=\"183\" class=\"wp-image-105112\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2025\/01\/a-black-and-white-rectangle-description-automatic.png\" alt=\"A black and white rectangle\n\nDescription automatically generated\" srcset=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2025\/01\/a-black-and-white-rectangle-description-automatic.png 1341w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2025\/01\/a-black-and-white-rectangle-description-automatic-300x41.png 300w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2025\/01\/a-black-and-white-rectangle-description-automatic-1024x140.png 1024w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2025\/01\/a-black-and-white-rectangle-description-automatic-768x105.png 768w\" sizes=\"auto, (max-width: 1341px) 100vw, 1341px\" \/><\/p>\n<p>That happens because, by default, <code>Receive-Job<\/code> details the results from the cache. When you run <code>Receive-Job<\/code> again, you get only the new results after the first run.<\/p>\n<p>To prevent that happening, use the <code>Keep<\/code> parameter.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"1350\" height=\"763\" class=\"wp-image-105113\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2025\/01\/word-image-105109-4.png\" srcset=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2025\/01\/word-image-105109-4.png 1350w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2025\/01\/word-image-105109-4-300x170.png 300w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2025\/01\/word-image-105109-4-1024x579.png 1024w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2025\/01\/word-image-105109-4-768x434.png 768w\" sizes=\"auto, (max-width: 1350px) 100vw, 1350px\" \/><\/p>\n<p>This way, you can use receive-job multiple times without deleting the cached data.<\/p>\n<p>You can also use the <code>Wait<\/code> parameter of the <code>Receive-Job<\/code> cmdlet. When using this parameter, the cmdlet does not return the command prompt until the job is completed and all results are available.<\/p>\n<h2>Getting a list of jobs<\/h2>\n<p>You may have jobs that take a long time to finish. Using the <code>Get-Job<\/code> cmdlet, you can get a list of the jobs running or completed.<\/p>\n<p>First, let&#8217;s run a job that will take a long time to finish.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"1345\" height=\"279\" class=\"wp-image-105114\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2025\/01\/a-screen-shot-of-a-computer-description-automatic-1.png\" alt=\"A screen shot of a computer\n\nDescription automatically generated\" srcset=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2025\/01\/a-screen-shot-of-a-computer-description-automatic-1.png 1345w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2025\/01\/a-screen-shot-of-a-computer-description-automatic-1-300x62.png 300w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2025\/01\/a-screen-shot-of-a-computer-description-automatic-1-1024x212.png 1024w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2025\/01\/a-screen-shot-of-a-computer-description-automatic-1-768x159.png 768w\" sizes=\"auto, (max-width: 1345px) 100vw, 1345px\" \/><\/p>\n<p>Now, let\u00b4s get the job list and its status.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"1334\" height=\"373\" class=\"wp-image-105115\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2025\/01\/word-image-105109-6.png\" srcset=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2025\/01\/word-image-105109-6.png 1334w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2025\/01\/word-image-105109-6-300x84.png 300w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2025\/01\/word-image-105109-6-1024x286.png 1024w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2025\/01\/word-image-105109-6-768x215.png 768w\" sizes=\"auto, (max-width: 1334px) 100vw, 1334px\" \/><\/p>\n<p>You can also use the <code>Wait-Job<\/code> cmdlet to wait for any or all the job results. <code>Wait-Job<\/code> lets you wait for one or more specific jobs or for all jobs.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"1332\" height=\"425\" class=\"wp-image-105116\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2025\/01\/a-screenshot-of-a-computer-screen-description-aut-1.png\" alt=\"A screenshot of a computer screen\n\nDescription automatically generated\" srcset=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2025\/01\/a-screenshot-of-a-computer-screen-description-aut-1.png 1332w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2025\/01\/a-screenshot-of-a-computer-screen-description-aut-1-300x96.png 300w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2025\/01\/a-screenshot-of-a-computer-screen-description-aut-1-1024x327.png 1024w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2025\/01\/a-screenshot-of-a-computer-screen-description-aut-1-768x245.png 768w\" sizes=\"auto, (max-width: 1332px) 100vw, 1332px\" \/><\/p>\n<p>As a result, the PowerShell prompt is suppressed until the job is completed.<\/p>\n<h2>Stopping a Job<\/h2>\n<p>To stop a background job, use the <code>Stop-Job<\/code> cmdlet. Let&#8217;s stop the job that is running.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"1350\" height=\"645\" class=\"wp-image-105117\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2025\/01\/a-screenshot-of-a-computer-screen-description-aut-2.png\" alt=\"A screenshot of a computer screen\n\nDescription automatically generated\" srcset=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2025\/01\/a-screenshot-of-a-computer-screen-description-aut-2.png 1350w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2025\/01\/a-screenshot-of-a-computer-screen-description-aut-2-300x143.png 300w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2025\/01\/a-screenshot-of-a-computer-screen-description-aut-2-1024x489.png 1024w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2025\/01\/a-screenshot-of-a-computer-screen-description-aut-2-768x367.png 768w\" sizes=\"auto, (max-width: 1350px) 100vw, 1350px\" \/><\/p>\n<h2>Deleting a Job<\/h2>\n<p>To delete a background job, use the <code>Remove-Job<\/code> cmdlet.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"1347\" height=\"613\" class=\"wp-image-105118\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2025\/01\/a-screenshot-of-a-computer-screen-description-aut-3.png\" alt=\"A screenshot of a computer screen\n\nDescription automatically generated\" srcset=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2025\/01\/a-screenshot-of-a-computer-screen-description-aut-3.png 1347w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2025\/01\/a-screenshot-of-a-computer-screen-description-aut-3-300x137.png 300w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2025\/01\/a-screenshot-of-a-computer-screen-description-aut-3-1024x466.png 1024w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2025\/01\/a-screenshot-of-a-computer-screen-description-aut-3-768x350.png 768w\" sizes=\"auto, (max-width: 1347px) 100vw, 1347px\" \/><\/p>\n<p>Let\u00b4s remove all jobs.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"1340\" height=\"178\" class=\"wp-image-105119\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2025\/01\/a-black-and-white-rectangle-description-automatic-1.png\" alt=\"A black and white rectangle\n\nDescription automatically generated\" srcset=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2025\/01\/a-black-and-white-rectangle-description-automatic-1.png 1340w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2025\/01\/a-black-and-white-rectangle-description-automatic-1-300x40.png 300w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2025\/01\/a-black-and-white-rectangle-description-automatic-1-1024x136.png 1024w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2025\/01\/a-black-and-white-rectangle-description-automatic-1-768x102.png 768w\" sizes=\"auto, (max-width: 1340px) 100vw, 1340px\" \/><\/p>\n<p>I also used the -force parameter to stop the job from running.<\/p>\n<h2>Why did my job fail?<\/h2>\n<p>Jobs can fail for many reasons. The job object contains a <code>Reason<\/code> property that will provide you with information about the cause of the failure. First, let&#8217;s store in a variable <code>$job<\/code> the result of the s<code>tart-job<\/code> with a failed option because I increased the time of the <code>start-sleep<\/code> parameter to more than int32<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"1342\" height=\"401\" class=\"wp-image-105120\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2025\/01\/a-computer-screen-shot-of-a-black-screen-descript.png\" alt=\"A computer screen shot of a black screen\n\nDescription automatically generated\" srcset=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2025\/01\/a-computer-screen-shot-of-a-black-screen-descript.png 1342w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2025\/01\/a-computer-screen-shot-of-a-black-screen-descript-300x90.png 300w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2025\/01\/a-computer-screen-shot-of-a-black-screen-descript-1024x306.png 1024w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2025\/01\/a-computer-screen-shot-of-a-black-screen-descript-768x229.png 768w\" sizes=\"auto, (max-width: 1342px) 100vw, 1342px\" \/><\/p>\n<h2>Sending values to a job<\/h2>\n<p>As the background job runs in another context, all the variables in the script are not visible in the job. We need to pass as <code>Argumentlist<\/code> parameter and in the script block add <code>param($variable)<\/code>.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"1342\" height=\"296\" class=\"wp-image-105121\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2025\/01\/a-screenshot-of-a-computer-description-automatica-7.png\" alt=\"A screenshot of a computer\n\nDescription automatically generated\" srcset=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2025\/01\/a-screenshot-of-a-computer-description-automatica-7.png 1342w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2025\/01\/a-screenshot-of-a-computer-description-automatica-7-300x66.png 300w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2025\/01\/a-screenshot-of-a-computer-description-automatica-7-1024x226.png 1024w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2025\/01\/a-screenshot-of-a-computer-description-automatica-7-768x169.png 768w\" sizes=\"auto, (max-width: 1342px) 100vw, 1342px\" \/><\/p>\n<h2>Being notified when a job finishes<\/h2>\n<p>We can do that, but we need to use another cmdlet <code>register-objectevent<\/code><em>. W<\/em>e will detect the change at the start of the job<\/p>\n<pre class=\"lang:ps theme:powershell-ise\">$job = start-job -ScriptBlock {param($seconds) Start-Sleep $seconds} -ArgumentList 10\nRegister-ObjectEvent -InputObject $job -EventName StateChanged -MessageData $job.Id -SourceIdentifier Job.Monitor -Action {\n    $Global:t = $event\n    Write-Host (\"Job ID {0} has changed from {1} to {2}\" -f  $t.sender.id,$t.SourceEventArgs.PreviousJobStateInfo.State,$t.SourceEventArgs.JobStateInfo.state) -ForegroundColor Green -BackgroundColor Black\n }<\/pre>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"1336\" height=\"454\" class=\"wp-image-105122\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2025\/01\/a-computer-screen-with-text-on-it-description-aut.png\" alt=\"A computer screen with text on it\n\nDescription automatically generated\" srcset=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2025\/01\/a-computer-screen-with-text-on-it-description-aut.png 1336w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2025\/01\/a-computer-screen-with-text-on-it-description-aut-300x102.png 300w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2025\/01\/a-computer-screen-with-text-on-it-description-aut-1024x348.png 1024w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2025\/01\/a-computer-screen-with-text-on-it-description-aut-768x261.png 768w\" sizes=\"auto, (max-width: 1336px) 100vw, 1336px\" \/><\/p>\n<h2>Using split-job<\/h2>\n<p><code>Split-job<\/code> is a community function that works with <a href=\"https:\/\/learn.microsoft.com\/en-us\/powershell\/scripting\/developer\/hosting\/creating-runspaces\">runspaces<\/a>, and IMHO is the best way to run your PowerShell code asynchronously with runspaces. The original can be found <a href=\"https:\/\/github.com\/mmessano\/PowerShell\/blob\/master\/Split-Job.ps1\">here<\/a>, but I made some changes and customized it. You can download that code in a .zip file <a href=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2025\/01\/PowerShell_Asychronous_Files.zip\">here from the Simple Talk site<\/a>.<\/p>\n<p>I would use split-job instead of PowerShell jobs because unlike PowerShell jobs I can set the number of concurrency parallel runspaces and not bloating the queue o jobs. For instance, I would need a code to control the parallel jobs and the queue to not bloat the jobs queue. Using split-job I just need to pass the parameter <code>-maxpipelines<\/code> that will say to me how any concurrency parallel jobs I want per time. Another point, as PowerShell jobs, it uses runspaces but explicitly in the code and not a black box like PowerShell hobs<\/p>\n<p>You need to execute the <code>split-job<\/code> cmdlet before the main foreach-object that runs the process. For instance,<\/p>\n<pre class=\"lang:ps theme:powershell-ise\">1..200 | \nSplit-Job {\nForEach-Object {\n    $_\n}}<\/pre>\n<p>When you set the <code>maxpipelines<\/code> parameter, each session runs in another runspace and the variables, functions are only visible in your runspace As it runs in another runspace all the variables that you want to pass to the main <code>foreach-object<\/code> you need to pass as parameter<\/p>\n<pre class=\"lang:ps theme:powershell-ise\">$var = 10\n1..200 | \nSplit-Job {\nForEach-Object {\n    \"$($_) and $var\"\n}} -Variable var<\/pre>\n<p>You can also control the number of pipelines sent to the system by using the parameter <code>maxpipelines<\/code>. That means that 50 runspaces will be opened asynchronously<\/p>\n<pre class=\"lang:ps theme:powershell-ise\">$var = 10\n1..200 | \nSplit-Job {\nForEach-Object {\n    \"$($_) and $var\"\n}} -Variable var -MaxPipelines 50<\/pre>\n<p>If you need to pass functions, you can use function parameter<\/p>\n<pre class=\"lang:ps theme:powershell-ise\">function Test {\n    write-host 'I am a function outside of the runspace'\n}<\/pre>\n<p>Then you can use it in the following code.<\/p>\n<pre class=\"lang:ps theme:powershell-ise\">$var = 10\n1..200 | \nSplit-Job {\nForEach-Object {\n    \"$($_) and $var\"\n    test\n}} -Variable var -MaxPipelines 50 -Function test<\/pre>\n<p>I did an example . a function that gets the computer from a specific AD group and uses the split-job to test if some services and processes are running.<\/p>\n<p>It is just an examples how powerful running asynchronous can be. If you have hundreds of servers to test as I do, you will want to run this way You can find that in the zip file where the split-job code is found <a href=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2025\/01\/PowerShell_Asychronous_Files.zip\">here from the Simple Talk site<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Imagine a candle that is lit and takes 1 hour to burn out. Now imagine one hundred candles. How many hours will it last? That depends. If they are lit simultaneously, it will take 1 hour. That is the basic idea of running in the background or asynchronously. Of course, the 100 candles can execute&#8230;&hellip;<\/p>\n","protected":false},"author":221715,"featured_media":105123,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[53,35],"tags":[],"coauthors":[6819],"class_list":["post-105109","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-featured","category-powershell"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/105109","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/users\/221715"}],"replies":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/comments?post=105109"}],"version-history":[{"count":1,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/105109\/revisions"}],"predecessor-version":[{"id":105124,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/105109\/revisions\/105124"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/media\/105123"}],"wp:attachment":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/media?parent=105109"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/categories?post=105109"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/tags?post=105109"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/coauthors?post=105109"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}