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

时间:2022-12-10 12:50:54

概述

  相信大家对后台任务处理不陌生,比如.Net的后台线程处理,Java的线程处理等等。

而当我们用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 10}
#创建一个等待5s的后台任务
$WaitJob2 = Start-Job -ScriptBlock {Sleep -Seconds 15}
#等待两个Job完成
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 -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。

6.引用&扩展阅读

以下链接为微软提供的技术资料:

http://technet.microsoft.com/library/2bc04935-0deb-4ec0-b856-d7290cca6442(v=wps.630).aspx