{"id":50983,"date":"2010-03-15T00:01:00","date_gmt":"2010-03-15T00:01:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2010\/03\/15\/hey-scripting-guy-how-can-i-start-receive-and-manage-jobs-in-windows-powershell-2-0\/"},"modified":"2010-03-15T00:01:00","modified_gmt":"2010-03-15T00:01:00","slug":"hey-scripting-guy-how-can-i-start-receive-and-manage-jobs-in-windows-powershell-2-0","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/hey-scripting-guy-how-can-i-start-receive-and-manage-jobs-in-windows-powershell-2-0\/","title":{"rendered":"Hey, Scripting Guy! How Can I Start, Receive, and Manage Jobs in Windows PowerShell 2.0?"},"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>&nbsp;<\/p>\n<p class=\"MsoNormal\">&nbsp;<\/p>\n<p><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! I have been thinking about writing a script and using the .NET Framework class <b>system.thread<\/b> to give me the ability to do multiple things at once. I need to perform a query of Active Directory Domain Services (AD DS) that will consume a decent amount of time. While waiting for that query to complete, I could be doing other things in my script. Therefore, I am thinking about implementing the <b>system.thread<\/b> class. If I do it as a function, I can easily re-use the code. What do you think? Is it doable? Have you written such a script yourself? <\/p>\n<p class=\"MsoNormal\">&#8212; FS<\/p>\n<p class=\"MsoNormal\">\n<p>&nbsp;<\/p>\n<\/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 FS, <\/p>\n<p class=\"MsoNormal\">Microsoft Scripting Guy Ed Wilson here. I am drinking a cup of <a href=\"http:\/\/en.wikipedia.org\/wiki\/English_Breakfast_tea\"><font face=\"Segoe\">English Breakfast<\/font><\/a> tea this morning with a stick of cinnamon in it, while listening to <a href=\"http:\/\/en.wikipedia.org\/wiki\/Mariza\"><font face=\"Segoe\">Mariza<\/font><\/a> sing <a href=\"http:\/\/en.wikipedia.org\/wiki\/Fado\"><font face=\"Segoe\">Fado<\/font><\/a>. It is a cool, but damp morning in Charlotte, North Carolina, and if I close my eyes, I can almost feel the gentle breezes of the Mediterranean Sea, and smell the <a href=\"http:\/\/en.wikipedia.org\/wiki\/Pastel_de_nata\"><font face=\"Segoe\">pastel de nata<\/font><\/a>. I spent a month in <a href=\"http:\/\/en.wikipedia.org\/wiki\/Lisbon\"><font face=\"Segoe\">Lisbon<\/font><\/a> a couple years ago while I was there teaching a series of Windows PowerShell classes, and it was a wonderful time. Here is a photograph of an old lighthouse that&nbsp;I snapped during a coastal drive with Luis, my friend and contact in Portugal.<\/p>\n<p class=\"Fig-Graphic\"><img decoding=\"async\" title=\"Photograph Ed took of a Spanish lighthouse\" alt=\"Photograph Ed took of a Spanish lighthouse\" src=\"http:\/\/img.microsoft.com\/library\/media\/1033\/technet\/images\/scriptcenter\/qanda\/hsg\/2010\/march\/hey0315\/hsg-03-15-10-01.jpg\" width=\"600\" height=\"516\"><\/p>\n<p class=\"Fig-Graphic\">In fact, my trick of putting cinnamon sticks in my tea is something I picked up in Lisbon. Of course, they put the cinnamon stick in their coffee, but I absconded with one of the cinnamon sticks and put it in my tea<span>&mdash;<\/span>and it worked out really well. What is cool is that by the end of the week, several of the students switched to the joys of tea, and they were using the cinnamon trick I learned from them that they learned from me. <\/p>\n<p class=\"MsoNormal\">FS, to answer directly your threading question: I have not written a script using the <b>system.thread<\/b> class, but I have thought about it. The reason I never got around to it is Windows PowerShell 2.0 introduces the concept of jobs. Using a job, either from the Windows PowerShell console or from within a script, allows you to start a long running procedure and return immediately to doing something else. <\/p>\n<p class=\"MsoNormal\">To start a job, you must first enable remoting. This may sound a little strange, but Windows PowerShell uses the remoting infrastructure to run the jobs. To enable remoting use the <b>Enable-PSRemoting<\/b> cmdlet. Keep in mind this command must be run as an administrator, and you will need to right-click the Windows PowerShell icon and choose <b>Run as administrator<\/b>. You will, more than likely, (depending on your User Account Control settings), see a prompt that asks you, &ldquo;Do you want to allow the following program to make changes to this computer?&rdquo; The prompt is a little misleading because you have not done anything yet; therefore, Windows PowerShell makes no changes to the system. After Windows PowerShell is running with Administrator rights, use the <b>Enable-PSRemoting<\/b> cmdlet to configure Windows PowerShell for remoting. A prompt will appear, unless you use the <b>&ndash;Force<\/b> parameter.<\/p>\n<p class=\"Fig-Graphic\"><img decoding=\"async\" title=\"Image of the Enable-PSRemoting prompt\" alt=\"Image of the Enable-PSRemoting prompt\" src=\"http:\/\/img.microsoft.com\/library\/media\/1033\/technet\/images\/scriptcenter\/qanda\/hsg\/2010\/march\/hey0315\/hsg-03-15-10-02.jpg\" width=\"600\" height=\"225\"><\/p>\n<p class=\"Fig-Graphic\">If you run the <b>Enable-PSRemoting<\/b> cmdlet with the <b>&ndash;Force<\/b> parameter, Windows PowerShell displays the output seen in the following image.<\/p>\n<p class=\"Fig-Graphic\"><img decoding=\"async\" title=\"Image of output when running Enable-PSRemoting cmdlet with -Force parameter\" alt=\"Image of output when running Enable-PSRemoting cmdlet with -Force parameter\" src=\"http:\/\/img.microsoft.com\/library\/media\/1033\/technet\/images\/scriptcenter\/qanda\/hsg\/2010\/march\/hey0315\/hsg-03-15-10-03.jpg\" width=\"600\" height=\"208\"><\/p>\n<p class=\"MsoNormal\">After remoting is configured, you can begin a new Windows PowerShell job by using the <b>Start-Job<\/b> cmdlet. The command is run as a job is placed in a script block, and the jobs are sequentially named <b>Job1<\/b>, <b>Job2<\/b>, and so on. This is shown here:<\/p>\n<p class=\"CodeBlock\"><span><font face=\"Lucida Sans Typewriter\">PS C:&gt; Start-Job -ScriptBlock { get-process }<\/p>\n<p>Id<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>Name<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>State<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>HasMoreData<span>&nbsp;&nbsp;&nbsp;&nbsp; <\/span>Location<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>Command<br \/>&#8212;<span>&nbsp;&nbsp; <\/span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/span>&#8212;-<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>&#8212;&#8211;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>&#8212;&#8212;&#8212;&#8211;<span>&nbsp;&nbsp;&nbsp;&nbsp; <\/span>&#8212;&#8212;&#8211;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>&#8212;&#8212;-<br \/>1<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>Job1<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>Running<span>&nbsp;&nbsp;&nbsp; <\/span>True<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>localhost<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>get-process<\/p>\n<p>PS C:&gt;<\/p>\n<p><\/font><\/span><\/p>\n<p class=\"MsoNormal\">The jobs receive job IDs that are also sequentially numbered. The first job created in a Windows PowerShell console is always job ID 1. You can use either the job ID or the job name to obtain information about the job. This is shown here:<\/p>\n<p class=\"CodeBlock\"><span><font face=\"Lucida Sans Typewriter\">PS C:&gt; Get-Job -Name job1<\/p>\n<p>Id<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>Name<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>State<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>HasMoreData<span>&nbsp;&nbsp;&nbsp;&nbsp; <\/span>Location<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>Command<br \/>&#8212;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>&#8212;-<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>&#8212;&#8211;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>&#8212;&#8212;&#8212;&#8211;<span>&nbsp;&nbsp;&nbsp;&nbsp; <\/span>&#8212;&#8212;&#8211;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>&#8212;&#8212;-<br \/>1<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>Job1<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>Completed<span>&nbsp; <\/span>True<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>localhost<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>get-process<\/p>\n<p>PS C:&gt; Get-Job -Id 1<\/p>\n<p>Id<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>Name <span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/span>State<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>HasMoreData<span>&nbsp;&nbsp;&nbsp;&nbsp; <\/span>Location<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>Command<br \/>&#8212;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>&#8212;-<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>&#8212;&#8211;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>&#8212;&#8212;&#8212;&#8211;<span>&nbsp;&nbsp;&nbsp;&nbsp; <\/span>&#8212;&#8212;&#8211;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>&#8212;&#8212;-<br \/>1<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>Job1<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>Completed<span>&nbsp; <\/span>True<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>localhost<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>get-process<\/p>\n<p>PS C:&gt;<\/p>\n<p><\/font><\/span><\/p>\n<p class=\"MsoNormal\">After you see that the job has completed, you can receive the job. The <b>Receive-Job<\/b> cmdlet returns the same information that is returned if a job is not used. The <b>Job1<\/b> output seen here (truncated to save space):<\/p>\n<p class=\"CodeBlock\"><span><font face=\"Lucida Sans Typewriter\">PS C:&gt; Receive-Job -Name job1<\/p>\n<p>Handles<span>&nbsp; <\/span>NPM(K)<span>&nbsp;&nbsp;&nbsp; <\/span>PM(K)<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>WS(K) VM(M)<span>&nbsp;&nbsp; <\/span>CPU(s)<span>&nbsp;&nbsp;&nbsp;&nbsp; <\/span>Id ProcessName<br \/>&#8212;&#8212;-<span>&nbsp; <\/span>&#8212;&#8212;<span>&nbsp;&nbsp;&nbsp; <\/span>&#8212;&#8211;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>&#8212;&#8211; &#8212;&#8211;<span>&nbsp;&nbsp; <\/span>&#8212;&#8212;<span>&nbsp;&nbsp;&nbsp;&nbsp; <\/span>&#8212; &#8212;&#8212;&#8212;&#8211;<br \/><span>&nbsp;&nbsp;&nbsp;&nbsp; <\/span>62<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>9<span>&nbsp;&nbsp;&nbsp;&nbsp; <\/span>1672<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>6032<span>&nbsp;&nbsp;&nbsp; <\/span>80<span>&nbsp;&nbsp;&nbsp;&nbsp; <\/span>0.00<span>&nbsp;&nbsp; <\/span>1408 apdproxy<br \/><span>&nbsp;&nbsp;&nbsp; <\/span>132<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>9<span>&nbsp;&nbsp;&nbsp;&nbsp; <\/span>2316<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>5632<span>&nbsp;&nbsp;&nbsp; <\/span>62<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>1364 atieclxx<br \/><span>&nbsp;&nbsp;&nbsp; <\/span>122<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>7<span>&nbsp;&nbsp;&nbsp;&nbsp; <\/span>1716<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>4232<span>&nbsp;&nbsp;&nbsp; <\/span>32<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>948 atiesrxx<br \/><span>&nbsp;&nbsp;&nbsp; <\/span>114<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>9<span>&nbsp;&nbsp;&nbsp; <\/span>14664<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>15372<span>&nbsp;&nbsp;&nbsp; <\/span>48<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>1492 audiodg<br \/><span>&nbsp;&nbsp;&nbsp; <\/span>556<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>62<span>&nbsp;&nbsp;&nbsp; <\/span>53928<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>5368<span>&nbsp;&nbsp; <\/span>616<span>&nbsp;&nbsp;&nbsp;&nbsp; <\/span>3.17<span>&nbsp;&nbsp; <\/span>3408 CCC<br \/><span>&nbsp;&nbsp;&nbsp;&nbsp; <\/span>58<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>8<span>&nbsp;&nbsp;&nbsp;&nbsp; <\/span>2960<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>7068<span>&nbsp;&nbsp;&nbsp; <\/span>70<span>&nbsp;&nbsp;&nbsp;&nbsp; <\/span>0.19<span>&nbsp;&nbsp;&nbsp; <\/span>928 conhost<br \/><span>&nbsp;&nbsp;&nbsp;&nbsp; <\/span>32<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>5<span>&nbsp;&nbsp;&nbsp;&nbsp; <\/span>1468<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>3468<span>&nbsp;&nbsp;&nbsp; <\/span>52<span>&nbsp;&nbsp;&nbsp;&nbsp; <\/span>0.00<span>&nbsp;&nbsp; <\/span>5068 conhost<br \/><span>&nbsp;&nbsp;&nbsp; <\/span>784<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>14<span>&nbsp;&nbsp;&nbsp;&nbsp; <\/span>3284<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>5092<span>&nbsp;&nbsp;&nbsp; <\/span>56<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>416 csrss<br \/><span>&nbsp;&nbsp;&nbsp; <\/span>529<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>27<span>&nbsp;&nbsp;&nbsp;&nbsp; <\/span>2928<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>17260<span>&nbsp;&nbsp; <\/span>145<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>496 csrss<br \/><span>&nbsp;&nbsp;&nbsp; <\/span>182<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>13<span>&nbsp;&nbsp;&nbsp;&nbsp; <\/span>8184<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>11152<span>&nbsp;&nbsp;&nbsp; <\/span>96<span>&nbsp;&nbsp;&nbsp;&nbsp; <\/span>0.50<span>&nbsp;&nbsp; <\/span>2956 DCPSysMgr<br \/><span>&nbsp;&nbsp;&nbsp; <\/span>135<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>11<span>&nbsp;&nbsp;&nbsp;&nbsp; <\/span>2880<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>7552<span>&nbsp;&nbsp;&nbsp; <\/span>56<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>2056 DCPSysMgrSvc<br \/><span>&nbsp;<\/span>&#8230; (truncated output)<\/p>\n<p><\/font><\/span><\/p>\n<p class=\"MsoNormal\">After a job has been received, that is it<span>&mdash;<\/span>the data is gone, unless you save it to a variable. The following code illustrates this concept:<\/p>\n<p class=\"CodeBlock\"><span><font face=\"Lucida Sans Typewriter\">PS C:&gt; Receive-Job -Name job1<br \/>PS C:&gt;<\/p>\n<p><\/font><\/span><\/p>\n<p class=\"MsoNormal\">What can be confusing about this is that the job still exists, and the <b>Get-Job<\/b> cmdlet continues to retrieve information about the job. This is shown here:<\/p>\n<p class=\"CodeBlock\"><span><font face=\"Lucida Sans Typewriter\">PS C:&gt; Get-Job -Name job1<\/p>\n<p>Id<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>Name<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>State <span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/span>HasMoreData<span>&nbsp;&nbsp;&nbsp;&nbsp; <\/span>Location<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>Command<br \/>&#8212;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>&#8212;-<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>&#8212;&#8211;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>&#8212;&#8212;&#8212;&#8211;<span>&nbsp;&nbsp;&nbsp;&nbsp; <\/span>&#8212;&#8212;&#8211;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>&#8212;&#8212;-<br \/>1<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>Job1<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>Completed<span>&nbsp; <\/span>False<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>localhost<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>get-process<\/p>\n<p>PS C:&gt;<\/p>\n<p><\/font><\/span><\/p>\n<p class=\"MsoNormal\">As a best practice, use the <b>Remove-Job<\/b> cmdlet to delete remnants of completed jobs when you are finished using the <b>job<\/b> object. This will avoid confusion regarding active jobs, completed jobs, and jobs waiting to be processed. After a job has been removed, the <b>Get-Job<\/b> cmdlet returns an error if you attempt to retrieve information about the job<span>&mdash;<\/span>because it no longer exists. This is illustrated here:<\/p>\n<p class=\"CodeBlock\"><span><font face=\"Lucida Sans Typewriter\">PS C:&gt; Remove-Job -Name job1<br \/>PS C:&gt; Get-Job -Name job1<br \/>Get-Job : The command cannot find the job because the job1 name was not found. Verify the value of the Name parameter,<br \/>and then try the command again.<br \/>At line:1 char:8<br \/>+ Get-Job &lt;&lt;&lt;&lt;<span>&nbsp; <\/span>-Name job1<br \/><span>&nbsp;&nbsp;&nbsp; <\/span>+ CategoryInfo<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>: ObjectNotFound: (job1:String) [Get-Job], PSArgumentException<br \/><span>&nbsp;&nbsp;&nbsp; <\/span>+ FullyQualifiedErrorId : JobWithSpecifiedNameNotFound,Microsoft.PowerShell.Commands.GetJobCommand<\/p>\n<p>PS C:&gt;<\/p>\n<p><\/font><\/span><\/p>\n<p class=\"MsoNormal\">When working with the job cmdlets, I like to give the jobs their own name. A job that returns process objects via the <b>Get-Process<\/b> cmdlet might be called <b>getProc<\/b>. A contextual naming scheme works better than trying to keep track of names such as <b>Job1<\/b> or <b>Job2<\/b>. Do not worry about making your job names too long, because you can use wildcard characters to simplify the typing requirement. When you receive the job, make sure you store the returned objects in a variable. This is shown here:<\/p>\n<p class=\"CodeBlock\"><span><font face=\"Lucida Sans Typewriter\">PS C:&gt; S\ntart-Job -Name getProc -ScriptBlock {get-process}<\/p>\n<p>Id<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>Name<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>State<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>HasMoreData<span>&nbsp;&nbsp;&nbsp;&nbsp; <\/span>Location<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>Command<br \/>&#8212;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>&#8212;-<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>&#8212;&#8211;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>&#8212;&#8212;&#8212;&#8211;<span>&nbsp;&nbsp;&nbsp;&nbsp; <\/span>&#8212;&#8212;&#8211;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>&#8212;&#8212;-<br \/>3<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>getProc<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>Running<span>&nbsp;&nbsp;&nbsp; <\/span>True<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>localhost<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>get-process<\/p>\n<p>PS C:&gt; Get-Job -Name get*<\/p>\n<p>Id<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>Name<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>State<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>HasMoreData<span>&nbsp;&nbsp;&nbsp;&nbsp; <\/span>Location<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>Command<br \/>&#8212;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>&#8212;-<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>&#8212;&#8211;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>&#8212;&#8212;&#8212;&#8211;<span>&nbsp;&nbsp;&nbsp;&nbsp; <\/span>&#8212;&#8212;&#8211;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>&#8212;&#8212;-<br \/>3<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>getProc<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>Completed<span>&nbsp; <\/span>True<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>localhost<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>get-process<\/p>\n<p>PS C:&gt; $procObj = Receive-Job -Name get*<br \/>PS C:&gt;<\/p>\n<p><\/font><\/span><\/p>\n<p class=\"MsoNormal\">After you have the returned object in a variable, you can use the object with other Windows PowerShell cmdlets. One thing to keep in mind is that the object is <a href=\"http:\/\/en.wikipedia.org\/wiki\/Serialization\"><font face=\"Segoe\">deserialized<\/font><\/a>. This is shown here where I use <b>gm<\/b> as an alias for the <b>Get-Member<\/b> cmdlet:<\/p>\n<p class=\"CodeBlock\"><span><font face=\"Lucida Sans Typewriter\">PS C:&gt; $procObj | gm<\/p>\n<p><span>&nbsp;&nbsp; <\/span>TypeName: Deserialized.System.Diagnostics.Process<\/p>\n<p><\/font><\/span><\/p>\n<p class=\"MsoNormal\">This means that not all the normal members from the <b>System.Diagnostics.Process<\/b> .NET Framework object are available. The normal methods are shown here (<b>gps<\/b> is an alias for the <b>Get-Process<\/b> cmdlet, <b>gm<\/b> is an alias for <b>Get-Member<\/b>, and <b>&ndash;m<\/b> is enough of the <b>&ndash;membertype<\/b> parameter to distinguish it on the Windows PowerShell console line):<\/p>\n<p class=\"CodeBlock\"><span><font face=\"Lucida Sans Typewriter\">PS C:&gt; gps | gm -m method<\/p>\n<p><span>&nbsp;&nbsp; <\/span>TypeName: System.Diagnostics.Process<\/p>\n<p>Name<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>&nbsp;<\/span>MemberType Definition<br \/>&#8212;-<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>&#8212;&#8212;&#8212;- &#8212;&#8212;&#8212;-<br \/>BeginErrorReadLine<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>Method<span>&nbsp;&nbsp;&nbsp;&nbsp; <\/span>System.Void BeginErrorReadLine()<br \/>BeginOutputReadLine<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>Method<span>&nbsp;&nbsp;&nbsp;&nbsp; <\/span>System.Void BeginOutputReadLine()<br \/>CancelErrorRead<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>Method<span>&nbsp;&nbsp;&nbsp;&nbsp; <\/span>System.Void CancelErrorRead()<br \/>CancelOutputRead<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>Method<span>&nbsp;&nbsp;&nbsp;&nbsp; <\/span>System.Void CancelOutputRead()<br \/>Close<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>Method<span>&nbsp;&nbsp;&nbsp;&nbsp; <\/span>System.Void Close()<br \/>CloseMainWindow<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>Method<span>&nbsp;&nbsp;&nbsp;&nbsp; <\/span>bool CloseMainWindow()<br \/>CreateObjRef<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>Method<span>&nbsp;&nbsp;&nbsp;&nbsp; <\/span>System.Runtime.Remoting.ObjRef CreateObjRef(type requestedType)<br \/>Dispose<span>&amp;<\/span><\/font><\/span><\/p>\n","protected":false},"excerpt":{"rendered":"<p>&nbsp; &nbsp; Hey, Scripting Guy! I have been thinking about writing a script and using the .NET Framework class system.thread to give me the ability to do multiple things at once. I need to perform a query of Active Directory Domain Services (AD DS) that will consume a decent amount of time. While waiting for [&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-50983","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; &nbsp; Hey, Scripting Guy! I have been thinking about writing a script and using the .NET Framework class system.thread to give me the ability to do multiple things at once. I need to perform a query of Active Directory Domain Services (AD DS) that will consume a decent amount of time. While waiting for [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/50983","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=50983"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/50983\/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=50983"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=50983"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=50983"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}