{"id":50963,"date":"2010-03-17T00:01:00","date_gmt":"2010-03-17T00:01:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2010\/03\/17\/hey-scripting-guy-how-can-i-use-windows-powershell-jobs-in-a-script\/"},"modified":"2010-03-17T00:01:00","modified_gmt":"2010-03-17T00:01:00","slug":"hey-scripting-guy-how-can-i-use-windows-powershell-jobs-in-a-script","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/hey-scripting-guy-how-can-i-use-windows-powershell-jobs-in-a-script\/","title":{"rendered":"Hey, Scripting Guy! How Can I Use Windows PowerShell Jobs in a Script?"},"content":{"rendered":"<p class=\"MsoNormal\"><a class=\"addthis_button\" href=\"http:\/\/www.addthis.com\/bookmark.php?v=250&amp;pub=scriptingguys\"><img decoding=\"async\" alt=\"Bookmark and Share\" src=\"http:\/\/s7.addthis.com\/static\/btn\/v2\/lg-share-en.gif\" width=\"125\" height=\"16\"><\/a><\/p>\n<p class=\"MsoNormal\">&nbsp;\n<img decoding=\"async\" title=\"Hey, Scripting Guy! Question\" border=\"0\" alt=\"Hey, Scripting Guy! Question\" align=\"left\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/q-for-powertip.jpg\" width=\"34\" height=\"34\"><\/p>\n<p class=\"MsoNormal\">Hey, Scripting Guy! Your examples this week on using Windows PowerShell jobs have all been from the command line. Is it possible to use Windows PowerShell jobs in a script? If so, how would I do it?<\/p>\n<p class=\"MsoNormal\">&#8212; AG<\/p>\n<p class=\"MsoNormal\">&nbsp;<\/p>\n<p class=\"MsoNormal\"><img decoding=\"async\" title=\"Hey, Scripting Guy! Answer\" border=\"0\" alt=\"Hey, Scripting Guy! Answer\" align=\"left\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/a-for-powertip.jpg\" width=\"34\" height=\"34\">Hello AG, <\/p>\n<p class=\"MsoNormal\">Microsoft Scripting Guy Ed Wilson at your service. The fog covers my front lawn like a down blanket draped casually across a <a href=\"http:\/\/www.oldandinteresting.com\/history-feather-beds.aspx\"><font face=\"Segoe\">feather tick<\/font><\/a>. My eyes reflect the early morning display of slumber, and my mind seems to echo the noisy silence brought about by last night&rsquo;s <a href=\"http:\/\/en.wikipedia.org\/wiki\/Temperature_inversion\"><font face=\"Segoe\">temperature inversion<\/font><\/a>. I was up late last night (or this early morning, depending on your perspective) on a conference call with my mentee Jit who lives in Canberra, Australia. Late at night in Charlotte is morning in Australia. We were talking about a huge Exchange migration project he is planning, and discussing various ways to use Windows PowerShell scripting to ease the transition as well as to facilitate the movement and consolidation of users. <\/p>\n<p class=\"MsoNormal\">I always enjoy talking with Jit because he is extremely smart. For obvious reasons, I prefer to talking to him in person as I did last year when I was down under teaching an advanced Windows PowerShell workshop (Australia is an awesome place. It&rsquo;s one of the Scripting Wife&rsquo;s favorite countries.) During one weekend there, Jit, Chris, Pete, the Scripting Wife, and I headed down to the shore to take pictures and to do some scuba diving. I took the following picture on our way to our second shore dive of the day. As you can see, it was kind of fun walking in my <a href=\"http:\/\/en.wikipedia.org\/wiki\/Dry_suit\"><span><font face=\"Segoe\">dry suit<\/font><\/span><\/a> carrying more than 100 pounds of equipment.<\/p>\n<p class=\"Fig-Graphic\"><img decoding=\"async\" title=\"Photograph Ed took on an Australian beach\" alt=\"Photograph Ed took on an Australian beach\" src=\"http:\/\/img.microsoft.com\/library\/media\/1033\/technet\/images\/scriptcenter\/qanda\/hsg\/2010\/march\/hey0317\/hsg-03-17-10-01.jpg\" width=\"600\" height=\"450\"><\/p>\n<p class=\"Fig-Graphic\">&nbsp;<\/p>\n<p class=\"MsoNormal\">AG, to use jobs in a script, you will use the same procedures we used <a href=\"http:\/\/blogs.technet.com\/heyscriptingguy\/archive\/2010\/03\/15\/hey-scripting-guy-march-15-2010.aspx\">on Monday<\/a> and <a href=\"http:\/\/blogs.technet.com\/heyscriptingguy\/archive\/2010\/03\/16\/hey-scripting-guy-march-16-2010.aspx\">on Tuesday<\/a>.<\/p>\n<p class=\"MsoNormal\">In the UseJobsToGetProcessAndService.ps1 script, two jobs are used. The first job uses the <b>Get-Process<\/b> cmdlet to return a list of processes, and the second job uses the <b>Get-Service<\/b> cmdlet to return a list of services. This is shown here:<\/p>\n<p class=\"CodeBlock\"><span><font face=\"Lucida Sans Typewriter\">Start-Job -Name process -ScriptBlock { Get-Process }<br \/>Start-Job -Name Service -ScriptBlock { Get-Service }<\/p>\n<p><\/font><\/span><\/p>\n<p class=\"MsoNormal\">On my computer, the script runs so fast that the jobs do not have time to complete, so I slowed it down by a few seconds to allow time for the jobs to complete. To do this, I used the <b>Start-Sleep<\/b> cmdlet and told it to wait for three seconds. This is shown here:<\/p>\n<p class=\"CodeBlock\"><span><font face=\"Lucida Sans Typewriter\">&#8220;Pausing for 3 seconds &#8230;&#8221;<br \/>start-sleep -Seconds 3<\/p>\n<p><\/font><\/span><\/p>\n<p class=\"MsoNormal\">After I am done pausing the script, I use the <b>Foreach<\/b> statement to loop through the jobs that have been registered on the computer. I use the <b>$job<\/b> variable to hold each job object that is returned from the <b>Get-Job<\/b> cmdlet. This is shown here:<\/p>\n<p class=\"CodeBlock\"><span><font face=\"Lucida Sans Typewriter\">Foreach ($job in Get-Job)<br \/><span>&nbsp;<\/span><\/p>\n<p><\/font><\/span><\/p>\n<p class=\"MsoNormal\">I do not want to attempt to receive the job if it is still running. Therefore, I check the state of the job by inspecting the <b>state<\/b> property on the <b>job<\/b> object. If the state of the job is reported as completed, I then use the <b>Receive-Job<\/b> cmdlet to return the completed job. Because I am only working with one job at a time, I can use the <b>job.id<\/b> property from the <b>job<\/b> object to receive the job. I also use the <b>command<\/b> property and the <b>id<\/b> property to display a status message before actually receiving the job. This is shown here:<\/p>\n<p class=\"CodeBlock\"><span><br \/><font face=\"Lucida Sans Typewriter\"><span>&nbsp; <\/span>if($job.state -eq &#8216;Completed&#8217;)<br \/><span>&nbsp;&nbsp;&nbsp; <\/span>{<br \/><span>&nbsp;&nbsp;&nbsp;&nbsp; <\/span>&#8220;Receiving job id $($job.id) which executes $($job.command)`r`n&#8221;<br \/><span>&nbsp;&nbsp;&nbsp;&nbsp; <\/span>Start-Sleep -Seconds 1<br \/><span>&nbsp;&nbsp;&nbsp;&nbsp; <\/span>Receive-Job -Id $job.id<br \/><span>&nbsp;&nbsp;&nbsp; <\/span>}<\/p>\n<p><\/font><\/span><\/p>\n<p class=\"MsoNormal\">If the job has not completed, I display a status message that states the job is still running. This is shown here:<\/p>\n<p class=\"CodeBlock\"><span><font face=\"Lucida Sans Typewriter\"><span>&nbsp; <\/span>else<br \/><span>&nbsp;&nbsp;&nbsp; <\/span>{<br \/><span>&nbsp;&nbsp;&nbsp;&nbsp; <\/span>&#8220;$($job.id ) job is still running $($job.command)&#8221;<br \/><span>&nbsp;&nbsp;&nbsp; <\/span>}<\/p>\n<p><\/font><\/span><\/p>\n<p class=\"MsoNormal\">The last thing I do is clear the job queue by using the <b>Get-Job<\/b> cmdlet to retrieve all job objects and pipelining it to the <b>Remove-Job<\/b> cmdlet. The force parameter is required to remove any jobs that may be still executing. In real life, you may not want to do this, but for the sake of a demonstration script, it makes sense. Besides, it could be a useful technique when you inadvertently create long-running jobs because of a programming error:<\/p>\n<p class=\"CodeBlock\"><span><font face=\"Lucida Sans Typewriter\">Get-Job | Remove-Job &ndash;force<\/p>\n<p><\/font><\/span><\/p>\n<p class=\"MsoNormal\">The complete UseJobsToGetProcessAndService.ps1 script is shown here.<\/p>\n<p class=\"CodeBlockScreenedHead\"><strong>UseJobsToGetProcessAndService.ps1<\/p>\n<p><\/strong><\/p>\n<p class=\"CodeBlock\"><span><font face=\"Lucida Sans Typewriter\">Start-Job -Name process -ScriptBlock { Get-Process }<br \/>Start-Job -Name Service -ScriptBlock { Get-Service }<br \/>&#8220;Pausing for 3 seconds &#8230;&#8221;<br \/>start-sleep -Seconds 3<\/p>\n<p>Foreach ($job in Get-Job)<br \/><span>&nbsp;<\/span>{<br \/><span>&nbsp; <\/span>if($job.state -eq &#8216;Completed&#8217;)<br \/><span>&nbsp;&nbsp;&nbsp; <\/span>{<br \/><span>&nbsp;&nbsp;&nbsp;&nbsp; <\/span>&#8220;Receiving job id $($job.id) which executes $($job.command)`r`n&#8221;<br \/><span>&nbsp;&nbsp;&nbsp;&nbsp; <\/span>Start-Sleep -Seconds 1<br \/><span>&nbsp;&nbsp;&nbsp;&nbsp; <\/span>Receive-Job -Id $job.id<br \/><span>&nbsp;&nbsp;&nbsp; <\/span>}<br \/><span>&nbsp; <\/span>else<br \/><span>&nbsp;&nbsp;&nbsp; <\/span>{<br \/><span>&nbsp;&nbsp;&nbsp;&nbsp; <\/span>&#8220;$($job.id ) job is still running $($job.command)&#8221;<br \/><span>&nbsp;&nbsp;&nbsp; <\/span>}<br \/><span>&nbsp;<\/span>}<br \/><span>&nbsp;<\/span>Get-Job | Remove-Job -force<\/p>\n<p><\/font><\/span><\/p>\n<p class=\"MsoNormal\">When the script runs inside the Windows PowerShell ISE, the output appears that is shown in the following image. The various <b>Start-Sleep<\/b> commands make it possible for you to easily see that each job is being retrieved. You have to carefully watch the output window, but you should be able to see each <b>job.id <\/b>and <b>job.command<\/b> displayed for a second before the information scrolls on the screen. <\/p>\n<p class=\"Fig-Graphic\"><img decoding=\"async\" title=\"Image of script output in Windows PowerShell ISE\" alt=\"Image of script output in Windows PowerShell ISE\" src=\"http:\/\/img.microsoft.com\/library\/media\/1033\/technet\/images\/scriptcenter\/qanda\/hsg\/2010\/march\/hey0317\/hsg-03-17-10-02.jpg\" width=\"600\" height=\"427\"><\/p>\n<p>AG, that is all there is to using jobs in a script. Windows PowerShell Jobs Week will continue tomorrow.\nIf you want to know exactly what we will be looking at tomorrow, follow us on <a href=\"http:\/\/bit.ly\/scriptingguystwitter\" target=\"_blank\"><font face=\"Segoe\">Twitter<\/font><\/a> or <a href=\"http:\/\/bit.ly\/scriptingguysfacebook\"><font face=\"Segoe\">Facebook<\/font><\/a>. If you have any questions, send e-mail to us at <a href=\"http:\/\/blogs.technet.commailto:scripter@microsoft.com\" target=\"_blank\"><font face=\"Segoe\">scripter@microsoft.com<\/font><\/a> or post your questions on the <a href=\"http:\/\/bit.ly\/scriptingforum\" target=\"_blank\"><font face=\"Segoe\">Official Scripting Guys Forum<\/font><\/a>. See you tomorrow. Until then, peace.<\/p>\n<p class=\"MsoNormal\">\n<p>&nbsp;<\/p>\n<\/p>\n<p><b><span>Ed Wilson and Craig Liebendorfer, Scripting Guys<\/p>\n<p><\/span><\/b><\/p>\n<p><b><span><\/span><\/b>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>&nbsp; Hey, Scripting Guy! Your examples this week on using Windows PowerShell jobs have all been from the command line. Is it possible to use Windows PowerShell jobs in a script? If so, how would I do it? &#8212; AG &nbsp; Hello AG, Microsoft Scripting Guy Ed Wilson at your service. The fog covers my [&hellip;]<\/p>\n","protected":false},"author":595,"featured_media":87096,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[51,85,3,4,45],"class_list":["post-50963","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-getting-started","tag-jobs","tag-scripting-guy","tag-scripting-techniques","tag-windows-powershell"],"acf":[],"blog_post_summary":"<p>&nbsp; Hey, Scripting Guy! Your examples this week on using Windows PowerShell jobs have all been from the command line. Is it possible to use Windows PowerShell jobs in a script? If so, how would I do it? &#8212; AG &nbsp; Hello AG, Microsoft Scripting Guy Ed Wilson at your service. The fog covers my [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/50963","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\/595"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/comments?post=50963"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/50963\/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=50963"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=50963"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=50963"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}