A scheduled task is an automated job managed by the Windows Task Scheduler engine that triggers scripts or binaries based on predefined intervals, system events, or user states. PowerShell's ScheduledTasks module lets you view, create, modify, and remove scheduled tasks entirely from the command line. Tasks are represented as Microsoft.Management.Infrastructure.CimInstance#Root/Microsoft/Windows/TaskScheduler/MSFT_ScheduledTask objects, constructed from modular actions, triggers, and principals.
Viewing Scheduled Tasks with Get-ScheduledTask
The Get-ScheduledTask cmdlet queries the Task Scheduler service and lists all scheduled tasks registered on the system. It returns CimInstance objects representing each task's definition and does not display run history.
Get-ScheduledTaskTaskPath TaskName State
-------- -------- -----
\ OneDrive Standalone Update Ready
\Microsoft\Windows\Power Efficiency Diagnostics\ AnalyzeSystem Ready
\ DailyBackup ReadyGetting a Specific Task
Use the -TaskName parameter to retrieve a single task by name.
Get-ScheduledTask -TaskName "DailyBackup"where -TaskName is the name of the task to retrieve; supports wildcards.
To view detailed run history and results:
Get-ScheduledTask -TaskName "DailyBackup" | Get-ScheduledTaskInfoLastRunTime : 5/10/2024 3:00:00 AM
LastTaskResult : 0
NextRunTime : 5/11/2024 3:00:00 AM
NumberOfMissedRuns : 0Filtering by Task Path
Task Scheduler organizes tasks hierarchically like a filesystem directory. By default, vendor and operating system tasks reside inside nested subdirectories (such as \Microsoft\Windows\Defrag\). Specifying -TaskPath "\" scopes the search to user-created tasks in the root folder, avoiding hundreds of internal Windows tasks.
Get-ScheduledTask -TaskPath "\" |
Select-Object -Property TaskName, State, @{Name="Actions"; Expression={$_.Actions.Execute}}where:
-TaskPathfilters by the directory container within the Task Scheduler tree (\indicates the root folder).Select-Objectretrieves selected fields, using an expression script block to extract executable paths from the nestedActionscollection.
./get-tasks-demo.ps1TaskName State Actions
-------- ----- -------
BackupScript Ready C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
SystemHealthAudit Ready C:\Scripts\audit.bat
OneDrive Reporting Ready C:\Program Files\OneDrive\OneDriveStandaloneUpdater.exeBuilding Blocks: Triggers and Actions
Before creating a task, you need two components: a trigger (when it runs) and an action (what it runs). A principal can also be supplied to define the security context.
Creating a Trigger with New-ScheduledTaskTrigger
The New-ScheduledTaskTrigger cmdlet defines when a task should execute.
$trigger = New-ScheduledTaskTrigger -Daily -At "3:00AM"where:
-Dailyspecifies the task recurs every day (other options:-Once,-Weekly,-AtLogOn,-AtStartup).-Atspecifies the time of day the task should trigger.
Creating an Action with New-ScheduledTaskAction
The New-ScheduledTaskAction cmdlet defines what the task executes.
$action = New-ScheduledTaskAction -Execute "powershell.exe" `
-Argument "-File C:\Scripts\backup.ps1"where:
-Executeis the executable to run (e.g.,powershell.exe,pwsh.exe,notepad.exe).-Argumentis the command-line arguments passed to the executable.
Combined Component Example
$action = New-ScheduledTaskAction -Execute "pwsh.exe" -Argument "-NoProfile -ExecutionPolicy Bypass -File C:\Scripts\RotateLogs.ps1"
$trigger = New-ScheduledTaskTrigger -Daily -At "2:30 AM"
Write-Output "Action Target: $($action.Execute) $($action.Arguments)"
Write-Output "Trigger Mode: Daily at $($trigger.StartBoundary)"where:
New-ScheduledTaskActiongenerates an action definition object.-Executespecifies the absolute path or registered system executable.-Argumentspecifies parameters passed to the executable upon invocation.New-ScheduledTaskTriggergenerates a trigger object defining timing constraints.-Dailycreates a recurring daily schedule.-Atspecifies the startup time of day.
./create-components.ps1Action Target: pwsh.exe -NoProfile -ExecutionPolicy Bypass -File C:\Scripts\RotateLogs.ps1
Trigger Mode: Daily at 2026-03-31T02:30:00Registering a New Task with Register-ScheduledTask
The Register-ScheduledTask cmdlet combines a trigger, an action, and optionally a principal or settings into a new scheduled task and registers it with the Windows Task Scheduler.
$trigger = New-ScheduledTaskTrigger -Daily -At "3:00AM"
$action = New-ScheduledTaskAction -Execute "powershell.exe" `
-Argument "-File C:\Scripts\backup.ps1"
Register-ScheduledTask -TaskName "DailyBackup" `
-Trigger $trigger `
-Action $action `
-Description "Runs the nightly backup script" `
-User "SYSTEM"where:
-TaskNameis the name assigned to the new scheduled task.-Triggeris the trigger object created withNew-ScheduledTaskTrigger.-Actionis the action object created withNew-ScheduledTaskAction.-Descriptionis an optional human-readable description of the task.-Useris the account context the task runs under (e.g.,SYSTEM, a domain user).
./create-backup-task.ps1TaskPath TaskName State
-------- -------- -----
\ DailyBackup ReadyUsing Settings and RunLevel
Add -RunLevel and -Settings for finer control over execution behavior.
$settings = New-ScheduledTaskSettingsSet -StartWhenAvailable -DontStopOnIdleEnd
Register-ScheduledTask -TaskName "DailyBackup" `
-Trigger $trigger `
-Action $action `
-Settings $settings `
-RunLevel Highestwhere:
-Settingsare additional behavior options (e.g., run as soon as possible if a scheduled start was missed).-RunLevel Highestruns the task with administrative privileges.
Using a Principal for Execution Context
$action = New-ScheduledTaskAction -Execute "powershell.exe" -Argument "-File C:\Scripts\Archive.ps1"
$trigger = New-ScheduledTaskTrigger -Daily -At "03:00 AM"
$principal = New-ScheduledTaskPrincipal -UserId "NT AUTHORITY\SYSTEM" -LogonType ServiceAccount -RunLevel Highest
Register-ScheduledTask -TaskName "DailyDataArchive" -TaskPath "\" -Action $action -Trigger $trigger -Principal $principal -Description "Daily archive of system metrics."where:
Register-ScheduledTaskwrites and activates the task within the Task Scheduler service.-TaskNameis the unique identifying name assigned to the task.-TaskPathis the folder location in the task tree where the definition will reside.-Actionis one or more action objects created byNew-ScheduledTaskAction.-Triggeris one or more trigger objects created byNew-ScheduledTaskTrigger.-Principalspecifies the security identity under which the task executes, generated viaNew-ScheduledTaskPrincipal.-Descriptionis an optional string explaining the administrative purpose of the task.
./register-task-demo.ps1TaskPath TaskName State
-------- -------- -----
\ DailyDataArchive ReadyRemoving a Task with Unregister-ScheduledTask
The Unregister-ScheduledTask cmdlet permanently removes an existing task and its definitions from the Task Scheduler database.
Unregister-ScheduledTask -TaskName "DailyBackup" -Confirm:$falsewhere:
-TaskNameis the name of the task to remove.-Confirm:$falsesuppresses the interactive confirmation prompt.
Practical Usage: Deploying a Weekly Maintenance Task
A common admin scenario is scheduling a maintenance script to run weekly, only when the target machine is powered on.
$trigger = New-ScheduledTaskTrigger -Weekly -DaysOfWeek Sunday -At "2:00AM"
$action = New-ScheduledTaskAction -Execute "powershell.exe" `
-Argument "-NoProfile -File C:\Scripts\maintenance.ps1"
$settings = New-ScheduledTaskSettingsSet -StartWhenAvailable
$existingTask = Get-ScheduledTask -TaskName "WeeklyMaintenance" -ErrorAction SilentlyContinue
if ($existingTask) {
Unregister-ScheduledTask -TaskName "WeeklyMaintenance" -Confirm:$false
}
Register-ScheduledTask -TaskName "WeeklyMaintenance" `
-Trigger $trigger `
-Action $action `
-Settings $settings `
-User "SYSTEM" `
-Description "Weekly system maintenance script"where:
$existingTaskchecks whether a task with the same name already exists.-ErrorAction SilentlyContinueprevents an error if the task isn't found.- The script unregisters any existing task before re-registering it, avoiding duplicate or conflicting task definitions.
./deploy-maintenance-task.ps1
Get-ScheduledTask -TaskName "WeeklyMaintenance"TaskPath TaskName State
-------- ------------------ -----
\ WeeklyMaintenance ReadyPractical Administration: Manual Invocation and Task Auditing
Administrators often need to deploy a task, manually run it to verify functionality, and inspect the last run result to ensure proper configuration.
$taskName = "MaintenanceAudit"
$action = New-ScheduledTaskAction -Execute "cmd.exe" -Argument "/c echo Maintenance Complete > C:\Logs\task_test.log"
$trigger = New-ScheduledTaskTrigger -Daily -At "11:00 PM"
Register-ScheduledTask -TaskName $taskName -Action $action -Trigger $trigger -Force | Out-Null
Start-ScheduledTask -TaskName $taskName
Start-Sleep -Seconds 2
$info = Get-ScheduledTaskInfo -TaskName $taskName
[PSCustomObject]@{
TaskName = $taskName
LastRunTime = $info.LastRunTime
LastTaskResult = $info.LastTaskResult
NextRunTime = $info.NextRunTime
}where:
-Forceoverwrites any existing task with the same name during registration.Out-Nulldiscards pipeline output fromRegister-ScheduledTaskfor clean console execution.Start-ScheduledTasktriggers the task out-of-schedule immediately.Start-Sleeptemporarily pauses script execution to allow the spawned process to execute and finish.Get-ScheduledTaskInforetrieves execution history, exit codes, and scheduled upcoming runs.LastTaskResultis the exit code returned by the last run (0denotes success).
./test-and-audit-task.ps1TaskName LastRunTime LastTaskResult NextRunTime
-------- ----------- -------------- -----------
MaintenanceAudit 3/31/2026 10:14:02 AM 0 3/31/2026 11:00:00 PM