概述
相信大家对后台任务处理不陌生,比如.Net的后台线程处理,Java的线程处理等等。
而当我们用PowerShell这个强大的工具时怎么样开启后台任务呢,以及怎样处理这些任务呢,本篇将会告诉你PowerShell后台任务处理。
1.什么时候会用到后台任务
当本地机器需要执行一个动作,此动作需要耗费很长时间,而机器在这段时间内只能等待,而我们希望在机器等待的这段时间内,我们还可以做其他事情。
这样我们就可以用后台任务来解决上面遇到的问题。
2.后台任务主要用在哪些场景
(1)将文件拷贝到多台远程机器,可以开启多个任务进行并行拷贝
(2)多台远程机器同时安装文件,可以开启多个任务进行并行安装
等等
3.PowerShell里面怎么开启后台任务
(1)Start-Job
代码语言:javascript复制1 $StartJob = Start-Job -ScriptBlock {Get-Process}
2 $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
代码语言:javascript复制1 $InvokeCommandJob = Invoke-Command -ComputerName LocalHost -ScriptBlock {Get-Process} -AsJob
2 $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
代码语言:javascript复制1 #创建一个等待1s的后台任务
2 $WaitJob1 = Start-Job -ScriptBlock {Sleep -Seconds 10}
3 #创建一个等待5s的后台任务
4 $WaitJob2 = Start-Job -ScriptBlock {Sleep -Seconds 15}
5 #等待两个Job完成
6 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,因为等待的时间不够长,如果将等待的超时时间改长一点就可以了,代码如下:
代码语言:javascript复制1 Wait-Job -Job $WaitJob1,$WaitJob2 -Timeout 10
还有一些等待Job完成的命令
代码语言:javascript复制1 Wait-Job -Id $WaitJob1.Id,$WaitJob2.Id -Timeout 10
2 Wait-Job -Name $WaitJob1.Name,$WaitJob2.Name -Timeout 10
3 Wait-Job -InstanceId $WaitJob1.InstanceId,$WaitJob2.InstanceId -Timeout 10
4 Wait-Job -State Running -Timeout 10
通过上面的例子我们可以通过设定Timeout的时间来监控Job的状态
(2)Remove-Job
代码语言:javascript复制1 Remove-Job -Id $WaitJob1.Id,$WaitJob2.Id
2 Remove-Job -Name $WaitJob1.Name,$WaitJob2.Name
3 Remove-Job -InstanceId $WaitJob1.InstanceId,$WaitJob2.InstanceId
4 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
代码语言:javascript复制1 Remove-Job -Job $WaitJob1,$WaitJob2 -Force
下面我来讲一个非常有趣的问题
5.Start-Job传参
比如我们现在要开启一个Job,计算$c=$a $b,然后将计算结果写入到D:a.txt文本文件中
代码语言:javascript复制
1 $a = 1
2 $b = 2
3 $c = 0
4 $Job = Start-Job -ScriptBlock {
5 $c = $a $b
6 $c > "D:a.txt"
7 }
OK,代码写好了,运行之后,我们期望得到的结果是D:a.txt文本文件中的内容为3
但是事实上文本文件中的内容为空,这是为什么呢?因为我们忽略了一个问题:
ScriptBlock里面的参数都是需要参数传递进去的。
修改上面的代码:
代码语言:javascript复制
1 $a = 1
2 $b = 2
3 $c = 0
4 $Job = Start-Job -ArgumentList $a,$b -ScriptBlock {
5 param($a,$b)
6 $c = $a $b
7 $c > "d:a.txt"
8 }
运行上面的代码,可以看到文本文件中的内容为3。
6.引用&扩展阅读
以下链接为微软提供的技术资料:
http://technet.microsoft.com/library/2bc04935-0deb-4ec0-b856-d7290cca6442(v=wps.630).aspx