PowerShell Schedule Task: Create Tasks with New-ScheduledTask

PowerShell Schedule Task: Create Tasks with New-ScheduledTask

PowerShell Tips Editor 3 min read
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%\System32 by default. Scripts referenced with relative paths like .\script.ps1 won’t be found. Always use full absolute paths in the -Argument string, 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 Bypass in 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.

Send-Item -To