PowerShell Schedule Task: Create Tasks with New-ScheduledTask

A script that runs once is a utility. A script that runs automatically on a schedule is automation. Windows Task Scheduler is the mechanism that turns PowerShell scripts into scheduled jobs — and PowerShell has full cmdlets to create, modify, and manage scheduled tasks without touching the Task Scheduler GUI. This guide covers how to PowerShell schedule script task scheduler: creating tasks with triggers, running as SYSTEM, modifying existing tasks, and managing task lifecycle.
Quick Answer / TL;DR
# Create a daily task to run a PowerShell script at 7 AM
$action = New-ScheduledTaskAction -Execute 'powershell.exe' `
-Argument '-NonInteractive -ExecutionPolicy Bypass -File "C:\Scripts\cleanup.ps1"'
$trigger = New-ScheduledTaskTrigger -Daily -At '7:00AM'
Register-ScheduledTask -TaskName 'DailyCleanup' -Action $action -Trigger $trigger
Create a Basic Scheduled Task
Creating a scheduled task requires three components: an action, a trigger, and registration:
# Step 1: Define what to run
$action = New-ScheduledTaskAction `
-Execute 'powershell.exe' `
-Argument '-NonInteractive -NoProfile -ExecutionPolicy Bypass -File "C:\Scripts\monitor.ps1"' `
-WorkingDirectory 'C:\Scripts'
# Step 2: Define when to run
$trigger = New-ScheduledTaskTrigger -Daily -At '6:00AM'
# Step 3: Register the task
Register-ScheduledTask `
-TaskName 'ServerMonitor' `
-TaskPath '\MyTasks\' `
-Action $action `
-Trigger $trigger `
-Description 'Daily server health check'
# Verify it was created
Get-ScheduledTask -TaskName 'ServerMonitor'
TaskPath TaskName State
-------- -------- -----
\MyTasks\ ServerMonitor Ready
The script path in -Argument must be an absolute path. Task Scheduler does not resolve relative paths — if you use .\script.ps1, the task will fail silently.
Set Triggers (Daily, Weekly, At Startup)
Task Scheduler supports many trigger types. Here are the most common:
# Daily at a specific time
$daily = New-ScheduledTaskTrigger -Daily -At '3:00AM'
# Weekly on specific days
$weekly = New-ScheduledTaskTrigger -Weekly -DaysOfWeek Monday, Wednesday, Friday -At '8:00AM'
# At system startup
$startup = New-ScheduledTaskTrigger -AtStartup
# At user logon
$logon = New-ScheduledTaskTrigger -AtLogOn
# Once, at a specific time
$once = New-ScheduledTaskTrigger -Once -At (Get-Date).AddMinutes(5)
# Multiple triggers on one task
Register-ScheduledTask -TaskName 'MultiTrigger' `
-Action $action `
-Trigger @($daily, $startup)
Run as SYSTEM Account
Running as SYSTEM allows the task to execute without a logged-in user and with elevated privileges:
# Create principal to run as SYSTEM
$principal = New-ScheduledTaskPrincipal -UserId 'SYSTEM' -RunLevel Highest
Register-ScheduledTask `
-TaskName 'SystemTask' `
-Action $action `
-Trigger $trigger `
-Principal $principal
# Alternatively, specify directly in Register-ScheduledTask
Register-ScheduledTask `
-TaskName 'SysTask2' `
-Action $action `
-Trigger $trigger `
-User 'SYSTEM' `
-RunLevel Highest
Tasks running as SYSTEM use the machine’s system execution policy. If you’re getting “scripts cannot be loaded” errors from a scheduled task, set the execution policy: Set-ExecutionPolicy RemoteSigned -Scope LocalMachine or include -ExecutionPolicy Bypass in the PowerShell argument string.
Modify an Existing Task
To modify a task’s action or settings after creation:
# Update the trigger time
$newTrigger = New-ScheduledTaskTrigger -Daily -At '4:00AM'
Set-ScheduledTask -TaskName 'ServerMonitor' -Trigger $newTrigger
# Update the action
$newAction = New-ScheduledTaskAction `
-Execute 'powershell.exe' `
-Argument '-File "C:\Scripts\monitor-v2.ps1"'
Set-ScheduledTask -TaskName 'ServerMonitor' -Action $newAction
# Update task settings (e.g., allow running on battery)
$settings = New-ScheduledTaskSettingsSet `
-AllowStartIfOnBatteries `
-DontStopIfGoingOnBatteries `
-ExecutionTimeLimit (New-TimeSpan -Hours 1)
Set-ScheduledTask -TaskName 'ServerMonitor' -Settings $settings
Enable, Disable, and Delete Tasks
# Enable a disabled task
Enable-ScheduledTask -TaskName 'ServerMonitor'
# Disable without deleting
Disable-ScheduledTask -TaskName 'ServerMonitor'
# Delete permanently
Unregister-ScheduledTask -TaskName 'ServerMonitor' -Confirm:$false
# List all tasks in a folder
Get-ScheduledTask -TaskPath '\MyTasks\' | Select-Object TaskName, State
# Run a task immediately (without waiting for trigger)
Start-ScheduledTask -TaskName 'ServerMonitor'
TaskName State
-------- -----
ServerMonitor Disabled
DailyCleanup Ready
Export and Import Task XML
Export a task definition to XML for documentation or deployment to other machines:
# Export task to XML
Export-ScheduledTask -TaskName 'ServerMonitor' |
Out-File 'C:\TaskDefinitions\ServerMonitor.xml' -Encoding UTF8
# Import task from XML on another machine
$xml = Get-Content 'C:\TaskDefinitions\ServerMonitor.xml' -Raw
Register-ScheduledTask -TaskName 'ServerMonitor' -Xml $xml
Common Errors and Fixes
-
Script path must be absolute — relative paths fail in Task Scheduler: Task Scheduler sets the working directory to
%SystemRoot%\System32by default. Scripts referenced with relative paths like.\script.ps1won’t be found. Always use full absolute paths in the-Argumentstring, wrapped in quotes if they contain spaces. -
Execution policy not set for SYSTEM account: The SYSTEM account may have a different (more restrictive) execution policy than your user account. Include
-ExecutionPolicy Bypassin the PowerShell argument list for all scheduled tasks:-Argument '-ExecutionPolicy Bypass -File "C:\Scripts\task.ps1"'.
Related Cmdlets / See Also
Wrapping Up
Creating scheduled tasks with PowerShell is a three-step process: action, trigger, register. Use absolute paths and -ExecutionPolicy Bypass in the argument list. Run as SYSTEM for unattended server tasks. Export task XML to deploy the same task to multiple machines. Your next step: take your most frequently run manual script and automate it with a scheduled task using the patterns in this guide.


