PowerShell is a powerful tool that can be used for a variety of tasks. Here are some tips on how to use PowerShell for jobs:
- Start by learning the basics of PowerShell. This will help you understand how it works and how to use it for tasks.
- Use cmdlets to perform tasks. cmdlets are short, easy-to-read commands that can be used to perform specific tasks.
- Use the Get-Command cmdlet to get information about a specific command or group of commands. This cmdlet will give you information about the command or group of commands that you are looking for.
- Use the Set-Command cmdlet to change or add commands to a specific group of commands. This cmdlet will add or change one or more commands in the group, rather than just adding one command to the group.
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.
Be sure to read the previous articles in the series:
Learn How to Automate Windows with PowerShell Learning to Use Cmdlets in PowerShell Learning How to Use Objects in PowerShell Learning Formatting, Filtering and Comparing in PowerShell Learn to Use Remoting in PowerShell Using PowerShell to Get Computer Information Working with Collections in PowerShell
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.
Now we are free to do whatever we want within the shell while that script block executes in the background.
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.
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.
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.
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.
This will remove it from the list of jobs that are returned by Get-Job.
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:
That was a simple command and should have finished executing by now so lets take a look at our jobs status.
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.
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.
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.
Alternatively, you can get the results from a specific child job using its job id.
WMI Jobs
WMI Jobs are much the same as Remote Jobs, requiring only the –AsJob parameter to be added to the Get-WmiObject cmdlet.
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:
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. 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. 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. 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.
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.
That’s all there is to it.