Introduction to PowerShell Scheduled Jobs

The Scripting Guys

Dr Scripto

Summary: Microsoft Scripting Guy, Ed Wilson, introduces the Windows PowerShell scheduled job feature.

Microsoft Scripting Guy, Ed Wilson, is here. In all the hubbub about all the great features introduced in Windows PowerShell 3.0, one (actually more than one) feature was somewhat overlooked. With Windows PowerShell 3.0 bringing features such as workflow, PowerShell Web Access, support for disconnected sessions, CIM cmdlets, updatable Help, module auto loading, and improved Windows PowerShell ISE, it was really understandable that the scheduled job feature was simply overlooked by nearly everyone. This is not because the feature is bad—it is just that all the other way cool stuff left little room on the plate of the average IT pro.

Note  I have written quite a bit about scheduled tasks and Windows PowerShell over the years. I have written about the classic scheduled tasks and the newer task scheduler. For more information, see this collection of blog posts.

It’s a job, it’s a scheduled task…

Windows PowerShell scheduled jobs rely on the background jobs feature that was introduced in Windows PowerShell 2.0. But unlike a plain old background job, Windows PowerShell 3.0 added the ability to schedule the background job. This makes Windows PowerShell scheduled jobs like a cross between a Windows PowerShell background job and Task Scheduler tasks.

Because Windows PowerShell scheduled jobs are, at their very heart, background jobs, it means that they run asynchronously in the background. It also means that I can use the *job cmdlets to manage Windows PowerShell scheduled jobs. Thereby, I protect my investment in learning Windows PowerShell in the first place. Start-Job, Get-Job, Stop-Job, and Receive-Job can be used to manage the Windows PowerShell scheduled jobs.

In addition to the generic *job cmdlets, Windows PowerShell 3.0 introduces a PSScheduledJob module that contains the following cmdlets:

PS C:\> Get-Command -Module PSScheduledJob | sort verb

CommandType     Name                                               ModuleName

———–     —-                                               ———-

Cmdlet          Add-JobTrigger                                     PSScheduledJob

Cmdlet          Disable-ScheduledJob                               PSScheduledJob

Cmdlet          Disable-JobTrigger                                 PSScheduledJob

Cmdlet          Enable-ScheduledJob                                PSScheduledJob

Cmdlet          Enable-JobTrigger                                  PSScheduledJob

Cmdlet          Get-ScheduledJobOption                             PSScheduledJob

Cmdlet          Get-ScheduledJob                                   PSScheduledJob

Cmdlet          Get-JobTrigger                                     PSScheduledJob

Cmdlet          New-ScheduledJobOption                             PSScheduledJob

Cmdlet          New-JobTrigger                                     PSScheduledJob

Cmdlet          Register-ScheduledJob                              PSScheduledJob

Cmdlet          Remove-JobTrigger                                  PSScheduledJob

Cmdlet          Set-ScheduledJobOption                             PSScheduledJob

Cmdlet          Set-ScheduledJob                                   PSScheduledJob

Cmdlet          Set-JobTrigger                                     PSScheduledJob

Cmdlet          Unregister-ScheduledJob                            PSScheduledJob

So, how does it work (or step-by-step)

Using the Windows PowerShell scheduled job cmdlets to create a scheduled job involves the following steps:

  1. Decide when to run the scheduled job.
  2. Decide how often to run the scheduled job.
  3. Decide what command to run.
  4. Create and configure the scheduled job.

Note  To create and schedule a Windows PowerShell scheduled job requires elevated permissions.

I create a trigger, but when I try to register the scheduled job, if I have not opened Windows PowerShell with admin rights, the following error message appears:

Image of error message

To launch with admin rights, right-click the Windows PowerShell icon and click Run as Administrator. The menu is shown in the following image:

Image of menu

After I open the Windows PowerShell console with admin rights, I create the trigger, and I register the scheduled job. The script to do this is:

$trigger = New-JobTrigger -Once -At

Register-ScheduledJob -Name GPS -Trigger $trigger -ScriptBlock {GPS}

This time, the command returns a ScheduledJobDefinition object. This object contains the name of the scheduled job, the job trigger, job ID, and the command itself. The command and the returned object are shown in the following image:

Image of command output

I can now use the Get-ScheduledJob cmdlet to check the status of the scheduled job as shown here:

PS C:\> Get-ScheduledJob -Id

Id         Name       JobTriggers     Command            Enabled

—         —-            ———–        ——-                    —–          GPS                  GPS                             True

If I want to see what job options were used when creating the scheduled job, I use the Get-ScheduledJobOption cmdlet. This command and associated output are shown here:

PS C:\> Get-ScheduledJobOption -Id

StartIfOnBatteries     : False

StopIfGoingOnBatteries : True

WakeToRun              : False

StartIfNotIdle         : True

StopIfGoingOffIdle     : False

RestartOnIdleResume    : False

IdleDuration           : 00:

IdleTimeout            : 0

ShowInTaskScheduler    : True

RunElevated            : False

RunWithoutNetwork      : True

DoNotAllowDemandStart  : False

MultipleInstancePolicy : IgnoreNew

JobDefinition          : Microsoft.PowerShell.ScheduledJob.ScheduledJobDefinition

If I want to see what trigger was used for the scheduled job, I first get the scheduled job, and then I pipe it to the Get-JobTrigger cmdlet. This command is shown here:

PS C:\> Get-ScheduledJob -Id | Get-JobTrigger

Id         Frequency       Time                   DaysOfWeek              Enabled

—         ———       —-                   ———-              ——-          Once            5/8/20 PM                            True

To see if the job ran, I use the Get-Job cmdlet as shown here:

PS C:\> get-job

Id     Name            PSJobTypeName   State         HasMoreData     Location

—     —-            ————-   —–         ———–     ——–

2      GPS             PSScheduledJob  Completed     True            localhost

3      GPS            PSScheduledJob  Completed     True            localhost

I see there are two jobs that completed. So I look at the first job. Notice that this number is a different ID number than the one I received from Get-ScheduledJob:

PS C:\> get-job -Id 2

Id     Name            PSJobTypeName   State         HasMoreData     Location

—     —-            ————-   —–         ———–     ——–

2      GPS             PSScheduledJob  Completed     True            localhost

To receive the results of the job, I use the Receive-Job cmdlet. To keep the results, I use the –Keep parameter. This will enable me to look at the results a second time. If I do not use the –Keep parameter, I will not be able to see the results a second time (unless I store the results in a variable or some other mechanism).

Receive-Job -Id 2 -Keep

The command and the output from the command are shown here:

Image of command output

That is all there is to playing around with Windows PowerShell scheduled jobs. Scheduled Job Week will continue tomorrow when I will talk about more cool stuff.

I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.

Ed Wilson, Microsoft Scripting Guy 

The Scripting Guys
Dr Scripto

Follow Dr Scripto   

No Comments.