首页 > 代码库 > 玩转PowerShell第一节——后台任务处理-技术&分享

玩转PowerShell第一节——后台任务处理-技术&分享

1.什么时候会用到后台任务

当本地机器需要执行一个动作,此动作需要耗费很长时间,而机器在这段时间内只能等待,而我们希望在机器等待的这段时间内,我们还可以做其他事情。

这样我们就可以用后台任务来解决上面遇到的问题。

2.后台任务主要用在哪些场景,举例说明

(1)将文件拷贝到多台远程机器,可以开启多个任务进行并行拷贝

(2)多台远程机器同时安装文件,可以开启多个任务进行并行安装

3.PowerShell里面怎么开启后台任务

(1)Start-Job

#$StartJob = Start-Job -ScriptBlock {Get-Process}
#$StartJob 
Id     Name            PSJobTypeName   State         HasMoreData     Location             Command       
--     ----            -------------   -----         -----------     --------             -------       
7      Job7            BackgroundJob   Running       True            localhost            Get-Process 

我们能够从上面看到
$StartJob名字叫做Job7,Job的类型为后台Job,状态为Running,Command表示执行的命令式Get-Process 

(2)Invoke-Command -AsJob

#$InvokeCommandJob  = Invoke-Command -ComputerName LocalHost -ScriptBlock {Get-Process} -AsJob
#$InvokeCommandJob
Id     Name            PSJobTypeName   State         HasMoreData     Location             Command                  
--     ----            -------------   -----         -----------     --------             -------                  
15     Job15           RemoteJob       Running       True            LocalHost            Get-Process 
我们能够从上面看到
$InvokeCommandJob的类型为后台RemoteJob,表示远程执行的Job,这里我用到的远程机器为LocalHost本地机器作为测试机器,
大家可以用远程机器名替换这个地方的LocalHost

开启了一个任务后,我们总不能不管它吧,现在来说下怎么处理这些Job

4.处理Job

(1)Wait-Job

#创建一个等待1s的后台任务
$WaitJob1  = Start-Job -ScriptBlock {Sleep -Seconds 1}
#创建一个等待5s的后台任务
$WaitJob2  = Start-Job -ScriptBlock {Sleep -Seconds 5}
#等待两个Job 2s内完成
Wait-Job -Job $WaitJob1,$WaitJob2 -Timeout 2
Id     Name            PSJobTypeName   State         HasMoreData     Location             Command                  
--     ----            -------------   -----         -----------     --------             -------                  
31     Job31           BackgroundJob   Completed     False           localhost            Sleep -Seconds 1         
33     Job33           BackgroundJob   Running       True            localhost            Sleep -Seconds 5 
从上面的执行结果可以看到$WaitJob2的状态为Running,因为等待的时间不够长,如果将等待的超时时间改长一点就可以了,代码如下:
Wait-Job -Job $WaitJob1,$WaitJob2 -Timeout 10
还有一些等待Job完成的命令
Wait-Job -Id $WaitJob1.Id,$WaitJob2.Id -Timeout 10
Wait-Job -Name $WaitJob1.Name,$WaitJob2.Name -Timeout 10
Wait-Job -InstanceId $WaitJob1.InstanceId,$WaitJob2.InstanceId -Timeout 10
Wait-Job -State Running -Timeout 10
通过上面的例子我们可以通过设定Timeout的时间来监控Job的状态

(2)Remove-Job

Remove-Job -Job $WaitJob1,$WaitJob2
Remove-Job -Id $WaitJob1.Id,$WaitJob2.Id
Remove-Job -Name $WaitJob1.Name,$WaitJob2.Name
Remove-Job -InstanceId $WaitJob1.InstanceId,$WaitJob2.InstanceId
Remove-Job -State Completed
Remove Job的时候一定要注意,如果该Job得状态不是完成的或者是停止的,就会抛出异常:
Remove-Job : The command cannot remove the job with the job ID 67 because the job is not finished. To remove the job, first
 stop the job, or use the Force parameter.
Parameter name: Job

如果要强制Remove Job,可以在后面添加一个参数-Force
Remove-Job -Job $WaitJob1,$WaitJob2 -Force

下面我来讲一个非常有趣的问题

5.Start-Job传参

比如我们现在要开启一个Job,计算$c=$a+$b,然后将计算结果写入到D:\a.txt文本文件中
$a = 1
$b = 2
$c = 0
$Job = Start-Job -ScriptBlock {
		$c = $a + $b
		$c > "D:\a.txt"
	}
OK,代码写好了,运行之后,我们期望得到的结果是D:\a.txt文本文件中的内容为3
但是事实上文本文件中的内容为空,这是为什么呢?因为我们忽略了一个问题:
ScriptBlock里面的参数都是需要参数传递进去的。
修改上面的代码:
$a = 1
$b = 2
$c = 0
$Job = Start-Job -ArgumentList $a,$b -ScriptBlock {
		param($a,$b)
		$c = $a + $b
		$c > "d:\a.txt"
	}
运行上面的代码,可以看到文本文件中的内容为3


玩转PowerShell第一节今天就写到这里,感谢各位博友看完这篇文章,
文章内容还有很多地方需要改进的,后面还会有更多的分享。
各位博友有任何问题,欢迎留言,我会及时跟大家进行沟通。


玩转PowerShell第一节——后台任务处理-技术&分享