Scheduled Tasks

A scheduled task is Windows' alarm clock for programs, a trigger that says when and an action that says what to run, built with New-ScheduledTaskTrigger and New-ScheduledTaskAction, handed to Task Scheduler with Register-ScheduledTask, and checked with Get-ScheduledTask.

Journeyman · PowerShell · Operating System · Updated

After this lesson you can

  • Build a task's trigger and action with New-ScheduledTaskTrigger and New-ScheduledTaskAction, running a script with pwsh -File and its full path
  • Register a task with Register-ScheduledTask, and check tasks and their last result with Get-ScheduledTask and Get-ScheduledTaskInfo

Key takeaways

  • A scheduled task is a trigger (when, such as every day at 6 PM) and an action (which program to run, and what to hand it).
  • New-ScheduledTaskTrigger and New-ScheduledTaskAction only build objects. Nothing on your PC changes until Register-ScheduledTask.
  • To run a script, the action runs pwsh.exe with -NoProfile -NonInteractive -File and the script's full path.
  • By default a task never starts on battery. -AllowStartIfOnBatteries and -StartWhenAvailable fix that for a laptop.
  • Get-ScheduledTask and Get-ScheduledTaskInfo show a PC's tasks and their last result; Task Scheduler shows the same tasks with the mouse.

Sam's laptop holds a whole term of school work: essays, lab reports, math homework. A copy on a backup drive every evening would mean a broken laptop costs a laptop, not a term. Sam has meant to make that copy by hand for weeks, and has done it twice. A phone reminder works until the evening something else comes up. Windows has a better answer built in, an alarm clock for programs: you say when and what, and it runs the job every day whether you remember or not. Windows uses it for dozens of its own jobs, and IT help-desk techs use it to run cleanups, reports and backups on every PC they look after.

Scheduled tasks are part of Windows, so this chapter is Windows only.

A task is a when and a what

Picture an alarm clock with a sticky note on it: "When this rings, back up school-work." The ring is the trigger: every day at 6 PM, every Monday, when you sign in, when the PC starts. The note is the action: the program to run, and what to hand it. Give the two a name and you have a scheduled task. The part of Windows that keeps the tasks, wakes up at the right moment and runs them is Task Scheduler.

PowerShell's commands for tasks share the noun ScheduledTask:

Get-Command -Noun ScheduledTask
CommandType     Name                                               Version    Source
-----------     ----                                               -------    ------
Function        Disable-ScheduledTask                              1.0.0.0    ScheduledTasks
Function        Enable-ScheduledTask                               1.0.0.0    ScheduledTasks
Function        Export-ScheduledTask                               1.0.0.0    ScheduledTasks
Function        Get-ScheduledTask                                  1.0.0.0    ScheduledTasks
Function        New-ScheduledTask                                  1.0.0.0    ScheduledTasks
Function        Register-ScheduledTask                             1.0.0.0    ScheduledTasks
Function        Set-ScheduledTask                                  1.0.0.0    ScheduledTasks
Function        Start-ScheduledTask                                1.0.0.0    ScheduledTasks
Function        Stop-ScheduledTask                                 1.0.0.0    ScheduledTasks
Function        Unregister-ScheduledTask                           1.0.0.0    ScheduledTasks

The parts of a task have commands of their own: New-ScheduledTaskTrigger, New-ScheduledTaskAction and New-ScheduledTaskSettingsSet.

The when: New-ScheduledTaskTrigger

$trigger = New-ScheduledTaskTrigger -Daily -At 6pm
$trigger | Select-Object DaysInterval, Enabled
DaysInterval Enabled
------------ -------
           1    True

-Daily -At 6pm reads "every day, at 6 PM", and DaysInterval 1 is "every 1 day". Type $trigger on its own and you'll see more of it, among it StartBoundary, the first time it rings. That one is written in world time, UTC, with a Z at the end, so it may not look like 6 PM: it's the same moment, and Task Scheduler shows it in your own time zone, as the 6 PM you asked for. Other triggers read as plainly: -Weekly -DaysOfWeek Monday, Thursday -At 7am, -AtLogOn (when you sign in) and -AtStartup (when the PC starts).

Building a trigger changes nothing on your PC. It's an object in a variable, and it's gone when you close the window.

The what: New-ScheduledTaskAction

Task Scheduler runs programs, not PowerShell commands. To run a script, the action runs pwsh.exe and hands it the script, the way Run It from Anywhere did with pwsh -File:

$action = New-ScheduledTaskAction -Execute 'pwsh.exe' -Argument '-NoProfile -NonInteractive -File "C:\Users\Sam\Scripts\Backup-SchoolWork.ps1"'
$action
Id               :
Arguments        : -NoProfile -NonInteractive -File "C:\Users\Sam\Scripts\Backup-SchoolWork.ps1"
Execute          : pwsh.exe
WorkingDirectory :
PSComputerName   :

-Execute is the program, and -Argument is everything typed after it, as one piece of text. It's in single quotes so the double quotes around the script's path stay inside: a path with a space in it still arrives as one path. -NonInteractive tells PowerShell nobody is there to answer, and the path is a full one, from C:\ down, because a task doesn't start in your folder. Scripts That Run Without You shows why both matter, with this Backup-SchoolWork.ps1. Put your own user name in the path.

Register it: Register-ScheduledTask

Up to here nothing has changed. Registering does: it hands the task to Task Scheduler, which keeps it until you remove it. A task that runs as you needs no administrator window. Read this section now, and run it when you have a script worth scheduling; the chapter's exercise gives you one.

First, the settings. A new task's defaults were made for desktop PCs:

New-ScheduledTaskSettingsSet | Select-Object DisallowStartIfOnBatteries, StopIfGoingOnBatteries, StartWhenAvailable
DisallowStartIfOnBatteries StopIfGoingOnBatteries StartWhenAvailable
-------------------------- ---------------------- ------------------
                      True                   True              False

On battery, the task never starts, and unplugging the laptop stops it halfway. And a laptop that's asleep at 6 PM misses the run. Three switches fix all three, and Register-ScheduledTask gives the task its name:

$settings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries -StartWhenAvailable
Register-ScheduledTask -TaskName 'School work backup' -Trigger $trigger -Action $action -Settings $settings

It answers with the new task's path (\), its name and its state, Ready. From then on Windows runs it every evening at 6 PM, as you, while you're signed in. Start-ScheduledTask -TaskName 'School work backup' runs it once right now, to test it; Disable-ScheduledTask pauses it; and Unregister-ScheduledTask -TaskName 'School work backup' removes it, after asking whether you're sure. New-ScheduledTask takes the same -Trigger, -Action and -Settings and hands the whole task back as an object, without registering it.

Looking at tasks: Get-ScheduledTask and the mouse's door

Looking is always safe. Windows keeps its own tasks in folders under \Microsoft\Windows\, and one runs on nearly every PC: the drive tidy-up.

Get-ScheduledTask -TaskPath '\Microsoft\Windows\Defrag\'
Get-ScheduledTask -TaskName ScheduledDefrag | Get-ScheduledTaskInfo
TaskPath                                       TaskName                          State
--------                                       --------                          -----
\Microsoft\Windows\Defrag\                     ScheduledDefrag                   Ready

LastRunTime        : 11/3/2026 7:58:43 AM
LastTaskResult     : 0
NextRunTime        :
NumberOfMissedRuns : 0
TaskName           : ScheduledDefrag
TaskPath           : \Microsoft\Windows\Defrag\
PSComputerName     :

LastTaskResult is the last run's exit code, and 0 means it worked. That number is how you'll know your backup ran, so Scripts That Run Without You makes sure it tells the truth. (This task has no NextRunTime because Windows runs it in its maintenance time instead of at an hour of its own.) Tasks you register live in the top folder, \: Get-ScheduledTask -TaskPath '\' lists them, along with any your apps have added.

The mouse's door is Task Scheduler itself: press Win+R, type taskschd.msc, and press Enter. Open Task Scheduler Library, then Microsoft, Windows and Defrag, and there's ScheduledDefrag, with tabs for its triggers, actions and history. A task you register from PowerShell appears in the library's top folder, and one you make with the mouse shows up in Get-ScheduledTask. Same tasks, two doors.

Task Scheduler with Task Scheduler Library, Microsoft, Windows and Defrag opened in the folder tree on the left, and ScheduledDefrag selected in the list, showing its status Ready and its Last Run Result, The operation completed successfully. (0x0)

Windows PowerShell 5.1 has the same commands. A Mac or Linux has no scheduled tasks: they schedule jobs with their own tools.

Check yourself

2 questions to try on the lesson page.

So what

A trigger and an action, registered once, and a job you'd forget happens every evening without you: that's how a script becomes a routine.

Key terms

Cheat sheets

Related