极客学校:学习如何在PowerShell中使用作业

极客学校:学习如何在PowerShell中使用作业

PowerShell has four types of jobs – Background Jobs, Remote Jobs,WMI Jobs and Scheduled Jobs. Join us as we find out what they are and how we can use them.

PowerShell具有四种类型的作业-后台作业,远程作业,WMI作业和计划的作业。 加入我们,了解它们的含义以及如何使用它们。

Be sure to read the previous articles in the series:

确保阅读本系列中的先前文章:

And stay tuned for the rest of the series all week.

并继续关注本系列的其余部分。

后台工作 (Background Jobs)

Until now everything I have shown you within PowerShell has been synchronous, meaning that we type something into the shell and can’t really do much until that command has finished executing. This is where background jobs come in. To start a background, job simply pass a script block to the Start-Job cmdlet.

到目前为止,我在PowerShell中向您显示的所有内容都是同步的,这意味着我们在shell中键入了一些内容,并且在该命令执行完毕之前并不能做很多事情。 这是后台作业进入的地方。要启动后台,作业只需将脚本块传递给Start-Job cmdlet。

Start-Job –Name GetFileList –Scriptblock {Get-ChildItem C:\ –Recurse}

开始作业–名称GetFileList –脚本块{Get-ChildItem C:\ –递归}

极客学校:学习如何在PowerShell中使用作业

Now we are free to do whatever we want within the shell while that script block executes in the background.

现在,当该脚本块在后台执行时,我们可以*地在shell中执行任何操作。

极客学校:学习如何在PowerShell中使用作业

When you kick off a new job, PowerShell creates a new job object that represents that job. You can get a list of all jobs at any time by running the Get-Job cmdlet.

启动新作业时,PowerShell将创建一个代表该作业的新作业对象。 您可以通过运行Get-Job cmdlet随时获取所有作业的列表。

极客学校:学习如何在PowerShell中使用作业

The job objects tell you about the status of the jobs. For example, in the above screenshot we can see that we have a BackgroundJob called GetFileList which is still running, but has already started returning data. If at any point you decide that the job has been running for too long, you can easily stop it by piping it to Stop-Job.

作业对象告诉您作业的状态。 例如,在上面的屏幕截图中,我们可以看到有一个名为GetFileList的BackgroundJob仍在运行,但已经开始返回数据。 如果您在任何时候认为作业已运行太长时间,则可以通过将其管道输送到Stop-Job轻松地停止它。

Get-Job –Name GetFileList | Stop-Job

Get-Job –名称GetFileList | 停止工作

极客学校:学习如何在PowerShell中使用作业

However, once you have stopped a job, whatever data it received up until the point that you stopped it is still available. There is a gotcha, though. In PowerShell, once you receive the results for a job, they get deleted. In order for them to remain, you must specify the keep switch parameter of Receive–Job.

但是,一旦停止了作业,直到停止之前所接收的任何数据仍然可用。 不过有一个陷阱。 在PowerShell中,一旦收到作业的结果,它们就会被删除。 为了保留它们,必须指定Receive–Job的keep开关参数。

Get-Job –Name GetFileList | Receive-Job –Keep

Get-Job –名称GetFileList | 接收工作–保持

极客学校:学习如何在PowerShell中使用作业

Once you are finished with a job, it is best practice to remove it. To remove the job, simply pipe it to the Remove-Job cmdlet.

完成工作后,最好将其删除。 若要删除作业,只需将其通过管道传递到Remove-Job cmdlet。

Get-Job –Name GetFileList | Remove-Job

Get-Job –名称GetFileList | 删除工作

This will remove it from the list of jobs that are returned by Get-Job.

这会将其从Get-Job返回的作业列表中删除。

极客学校:学习如何在PowerShell中使用作业

远程作业 (Remote Jobs)

A few lessons ago, we looked at how we can use remoting to execute PowerShell commands on a remote machine using Invoke-Command, but did you know you can also use Invoke-Command to kick off a  remoting job in the background? To do so, simply add the –AsJob parameter onto the end of your command:

几节课之前,我们研究了如何使用远程调用Invoke-Command在远程计算机上执行PowerShell命令,但是您是否知道也可以使用Invoke-Command在后台启动远程任务? 为此,只需在命令末尾添加–AsJob参数:

Invoke-Command -ComputerName Flash,Viper -Credential administrator -ScriptBlock {gci} –AsJob

调用命令-ComputerName Flash,Viper-凭据管理员-ScriptBlock {gci} –AsJob

极客学校:学习如何在PowerShell中使用作业

That was a simple command and should have finished executing by now so lets take a look at our jobs status.

这是一个简单的命令,现在应该已经完成​​执行,因此让我们看一下我们的作业状态。

极客学校:学习如何在PowerShell中使用作业

Hmm, looks like it failed. This brings me onto my first gotcha with jobs. When you create a new job of any type in PowerShell, it creates one parent job in addition to one child job for every computer that you are running the job against. When you use the Get-Job cmdlet, it only shows you the parent jobs, and the state property is worst case scenario, meaning that even if the command only failed to run on one out of a hundred computers, the parent jobs state will say failed. To see a list of child jobs you need to use the IncludeChildJob parameter.

嗯,看起来好像失败了。 这使我进入了工作的第一个陷阱。 当您在PowerShell中创建任何类型的新作业时,除了为每个要运行该作业的计算机创建一个子作业外,它还会创建一个父作业。 当您使用Get-Job cmdlet时,它仅向您显示父作业,并且state属性是最坏的情况,这意味着即使命令仅无法在一百台计算机中的一台上运行,父作业的状态也会显示失败了 要查看子作业列表,您需要使用IncludeChildJob参数。

极客学校:学习如何在PowerShell中使用作业

If you look closer, you will see that the job did indeed only fail on one computer, which brings us onto the next gotcha. When you try and get the results for the job, if you specify the parent’s job name or ID, PowerShell will return the data from all the child jobs. The problem is that if there is was an error in one of the child jobs, we are going to be left with some red text.

如果您仔细观察,您会发现该工作确实仅在一台计算机上失败,这使我们进入了下一个陷阱。 尝试获取作业结果时,如果指定父项的作业名或ID,PowerShell将返回所有子项作业的数据。 问题是,如果其中一个子作业出现错误,我们将剩下一些红色文字。

极客学校:学习如何在PowerShell中使用作业

There are two ways of getting around this. Firstly, if you know what computers you want the results for, you can simply use the ComputerName parameter of the Recieve –Job cmdlet.

解决此问题的方法有两种。 首先,如果您知道要使用哪些计算机作为结果,则可以只使用Recieve –Job cmdlet的ComputerName参数。

Get-Job –Id 3 | Receive-Job –Keep –ComputerName Viper

求职–Id 3 | 接收作业–保留–ComputerName毒蛇

极客学校:学习如何在PowerShell中使用作业

Alternatively, you can get the results from a specific child job using its job id.

或者,您可以使用特定的子作业的作业ID获得结果。

Get-Job -Id 3 –IncludeChildJob

Get-Job -Id 3 –IncludeChildJob

极客学校:学习如何在PowerShell中使用作业

Get-Job -Id 5 | Receive-Job –Keep

Get-Job -Id 5 | 接收工作–保持

极客学校:学习如何在PowerShell中使用作业

WMI工作 (WMI Jobs)

WMI Jobs are much the same as Remote Jobs, requiring only the –AsJob parameter to be added to the Get-WmiObject cmdlet.

WMI作业与远程作业非常相似,只需要将–AsJob参数添加到Get-WmiObject cmdlet。

极客学校:学习如何在PowerShell中使用作业
极客学校:学习如何在PowerShell中使用作业

Unfortunately, this means that they are also subject to the same gotchas I mentioned in the Remote Jobs section.

不幸的是,这意味着它们也受到我在“远程作业”部分中提到的陷阱的约束。

预定的工作 (Scheduled Jobs)

The last three kinds of jobs we looked at were not persistent, meaning that they are only available in your current session. Basically, that means if you kick off a job and then open another PowerShell Console and run Get-Job, you won’t see any jobs. However, come back to the console you kicked the job off from, you will be able to see its status. This is in contrast to Scheduled Jobs which are persistent. Basically, a Scheduled Job is a script block that runs on a schedule. In the past, the same affect could have been achieved using the Windows Task Scheduler, which is really what is happening underneath the hood. To create a new Scheduled Job, we do the following:

我们查看的最后三种作业不是持久性的,这意味着它们仅在您当前的会话中可用。 基本上,这意味着如果您启动工作,然后打开另一个PowerShell控制台并运行Get-Job,则不会看到任何工作。 但是,回到开始工作的控制台,您将能够看到其状态。 这与持久性计划作业相反。 基本上,计划作业是按计划运行的脚本块。 过去,使用Windows Task Scheduler可能会获得相同的效果,而实际上这是引擎盖下发生的事情。 要创建新的计划作业,我们执行以下操作:

Register-ScheduledJob -Name GetEventLogs -ScriptBlock {Get-EventLog -LogName Security -Newest 100} -Trigger (New-JobTrigger -Daily -At 5pm) -ScheduledJobOption (New-ScheduledJobOption -RunElevated)

Register-ScheduledJob -Name GetEventLogs -ScriptBlock {Get-EventLog -LogName安全-最新100} -Trigger(New-JobTrigger-每天-下午5点)-ScheduledJobOption(New-ScheduledJobOption -RunElevated)

There is quite a lot going on in that command, so let’s break it down.

该命令有很多事情要做,所以让我们分解一下。

  • First, we give our Scheduled Job a name of GetEventLogs.

    首先,我们为“计划作业”命名为GetEventLogs。
  • We then tell it that when triggered, we want it to run the contents of the specified script block, which basically gets the newest 100 entries of the Security event log.

    然后,我们告诉它,当被触发时,我们希望它运行指定脚本块的内容,该脚本块基本上会获取安全事件日志的最新100个条目。
  • Next, we specify a trigger. Since the trigger parameter takes a trigger object as input, we used a parenthetical command to generate a trigger that will go off every day at 5PM.

    接下来,我们指定一个触发器。 由于trigger参数将触发器对象作为输入,因此我们使用括号命令生成触发器,该触发器每天下午5点关闭。
  • Since we are dealing with the event log, we need to run as an administrator, which we can specify by creating a new ScheduledJobOption object and passing it to the ScheduledJobOption parameter.

    由于我们正在处理事件日志,因此需要以管理员身份运行,可以通过创建新的ScheduledJobOption对象并将其传递给ScheduledJobOption参数来指定。
极客学校:学习如何在PowerShell中使用作业

Since this is a slightly different type of job, you will also need to use a different command to retrieve a list of all the scheduled jobs on a machine.

由于这是一种稍有不同的作业类型,因此您还需要使用其他命令来检索计算机上所有已调度作业的列表。

Get-ScheduledJob

计划作业

极客学校:学习如何在PowerShell中使用作业

That’s all there is to it.

这里的所有都是它的。

翻译自: https://www.howtogeek.com/138856/geek-school-learn-how-to-use-jobs-in-powershell/