Latest posts by Mike Kanakos (see all)
- Monitoring Active Directory with the PowerShell module PSADHealth - Mon, Jan 20 2020
- Invoke-Command: Compensating for slow responding computers - Tue, Jan 7 2020
- Invoke-Command: Connecting to computers requiring different credentials - Tue, Dec 31 2019
Scheduled jobs vs. scheduled tasks ^
Scheduled jobs are batch jobs that run as background tasks created and managed using PowerShell. On the surface, scheduled jobs look, act, and feel much like an old Windows standard: scheduled tasks. The similarity between the two tools often confuses people. For the most part, scheduled jobs and scheduled tasks are the same but apply to different use cases. Microsoft modeled scheduled jobs to be similar to scheduled tasks on purpose so you wouldn't have to learn a new syntax for scheduling.
Scheduled tasks are native to Windows, aiming to interact with Windows and run Windows programs. Similarly, scheduled jobs are native to Windows PowerShell and cannot interact with Windows applications like Notepad, Word, or IE, for example.
So, what's so great about scheduled jobs then? While there are more than a few differences between the two, the biggest difference is with the job results. Scheduled tasks interact with Windows, but they do not capture any results from the tasks performed. Scheduled jobs are essentially PowerShell scripts, and as such, the results of the jobs are objects just like anything else you do with PowerShell. It stores the object data with the results.
If you created a scheduled job to get the running services on a computer, the results data would capture all the information about the services at the time of the job's execution. If you had a scheduled job that pinged a server, it would capture the ping results. It's like you get to go back in time and see what the data looked like at the time of its creation. As I mentioned earlier, since the results are essentially objects, you can manipulate that data and do things like pass the data to other cmdlets if need be. If you created a scheduled task that performs an action, the system does not capture the results of that action anywhere.
Let me briefly discuss management options—here's where it gets confusing. You can only create PowerShell scheduled jobs from the command line. Scheduled tasks have their own set of cmdlets for creation and management. You can use scheduled task cmdlets to view and manage scheduled jobs but not create jobs.
The Windows tool to interact with scheduled tasks is called Task Scheduler. You can create scheduled tasks from Task Scheduler but not scheduled jobs. However, you can view and manage scheduled jobs with the Task Scheduler, but you cannot use the scheduled job cmdlets to manage scheduled tasks in any way. Yes, it is a lot to try and keep track of, and I blame Microsoft for having too many options here.
I also want to point out that I am highlighting the biggest differences between the two technologies, but there are some other subtle differences I don't have the room to explain here. I recommend you read an excellent article from Microsoft that dives deep into the two tools and explains all the differences in depth.
The thing about scheduled jobs that should appeal to you, the administrator, is that you can manage the entire process of creating, managing, deleting, and reviewing results from the command line. You don't need to interact with the GUI at all. Since the PowerShell scheduled jobs are code, you can save them as scripts. If disaster strikes, you can re-run your scripts and have the scheduled jobs back in place in minutes!
Creating a scheduled job ^
You should be thinking about the following questions when you create your first scheduled job. I'll run through an example and show you how to build up the code based on the answers to the questions.
- When will the job run?
- How often will the job run?
- What code/cmdlets will the code run?
- What options are necessary to configure the scheduled job?
- Under what credentials will the job run?
- What will be the name of the job?
Let's walk through each question and start to build the syntax.
When will the job run? How often will the job run?
A job trigger starts a scheduled job. The cmdlet New-JobTrigger will define how often the job will run (e.g., once, daily, weekly, random, etc.) and when it will start (e.g., Monday at 1:30 p.m.).
$trigger = New-JobTrigger -Once -At 1:30PM
What code/cmdlets will the job run? The code that your scheduled job will run can either be a script block if the code is small enough, or it can call a file.
What options are necessary for the job to run?
Options are the conditions that may be required for the job to run, controlled through the New-ScheduledJobOption cmdlet. These are choices such as RUNELEVATED or STARTIFONBATTERY or REQUIRENETWORK. There are others, but I hope from my brief example you understand these are the more complex options you could use for a job. A scheduled job may have no options at all, but more often than not, they'll have defined options.
$opt = New-ScheduledJobOption -RunElevated -RequireNetwork
Under what credentials will the job run?
We use the Get-Credential cmdlet to consume credentials for the job to "run as."
$cred = Get-Credential -UserName company\someuser
What will be the name of the job? The -name parameter defines the job name
One last piece I didn't mention yet is defining how many instances of the job we want to save. Think of this as the job history option. How much history do I want to save? If we don't define this, the default is 32 instances, which may be overkill depending on what your job is doing. Keep in mind, scheduled jobs will save the output. This setting controls how much history you have to look through later on.
Now you can take all of that info and build a new job. You use the Register-ScheduledJob cmdlet to pull it all together.
Register-ScheduledJob -Name Test-DCsAreOnline -Trigger $trigger -Credential $cred `
-FilePath c:\scripts\test-dconline.ps1 -MaxResultCount 5 -ScheduledJobOption $opt
Let's see another example of defining a scheduled job. This time we're defining all of our variables like we would in a script. This scheduled job runs a script that checks the disk space on domain controllers every 12 hours and saves the last 10 results.
#Define the interval to repeat the job
$trigger = New-JobTrigger -Once -At 9:00AM -RepetitionInterval (New-TimeSpan -Hours 12) -RepeatIndefinitely
#Get user credential so that the job has access to the network
$cred = Get-Credential -UserName bigfirm.biz\someuser
#Set job options
$opt = New-ScheduledJobOption -RunElevated -RequireNetwork
Register-ScheduledJob -Name Get-DCDiskSpace -Trigger $trigger -Credential $cred `
-FilePath c:\scripts\Get-DCDiskSpace.ps1 -MaxResultCount 10 ScheduledJobOption $opt
You can save this code to create a new scheduled job so you can easily run it again in the future or use it as a template to create more scheduled jobs.
Displaying scheduled jobs ^
You can view your scheduled jobs two ways: PowerShell or in the GUI. First let's take a look at viewing them from PowerShell. One simple command Get-ScheduledJob shows all of your scheduled jobs.
PS C:\scripts> get-scheduledjob | ft -auto
Id Name JobTriggers Command Enabled
-- ---- ----------- ------- -------
1 Test-DCsOnline 1 D:\PowerShell_Scripts\AD-Health-Checks\Test-DCsOnline.ps1 False
Remember earlier when I mentioned you could manage your scheduled jobs with the Task Scheduler? You can view and manage scheduled jobs from the command line or from within the Task Scheduler. However, even though you use the Task Scheduler to view your scheduled jobs, they live in a different location in the Task Scheduler window than scheduled tasks.
This first screenshot is of the Task Scheduler. The line items are scheduled tasks, not scheduled jobs.
When using the Task Scheduler to manage your scheduled jobs, you need to look in a different location for the scheduled jobs.
If you go back and look at where I showed you how to view scheduled jobs in PowerShell, you'll notice that the command line ignored the scheduled tasks and only returned scheduled jobs. If you manage your scheduled jobs from the command line, one simple cmdlet Get-ScheduledJob gives you your results.
If you decide to manage your jobs in the Task Scheduler GUI, you need to remember it lists scheduled jobs in a different location than the default scheduled tasks, and, yes, I know this is confusing and a bit silly. That's also why I mentioned at the beginning of this article that it is a bad idea to manage your scheduled jobs in the GUI; it's just confusing to keep track of all the caveats when doing so.
I've given you a quite a bit of information to digest, but I'm far from done. Keep an eye out next week for a follow-up article on managing your scheduled jobs and viewing the results of completed jobs.
Please leave me some feedback in the comments section so I can continue to write useful articles. If there is something you'd like to see me write about or if you have a specific question about this or any or my other articles, please feel free to leave me a note as well.
In my next post I will explain how to manage scheduled jobs with PowerShell.