How to Configure Windows Server 2019 Scheduled Tasks
Scheduled Tasks in Windows Server 2019 allow administrators to automate scripts, programs, and maintenance operations at specified times or in response to system events. The Windows Task Scheduler service manages task execution, supports complex trigger conditions, handles security contexts for running tasks, and provides logging of task outcomes. PowerShell’s ScheduledTasks module provides full programmatic control over all task scheduler functionality.
Task Scheduler Architecture
A scheduled task consists of four main components. The trigger defines when the task runs — at a specific time, on a schedule, at system startup, at user logon, on an event log entry, or when a workstation becomes idle. The action specifies what to execute — a program or PowerShell script. The conditions define optional constraints such as whether the machine must be idle, plugged in to AC power, or connected to a specific network. The settings control behaviour such as what happens if the task is already running, how long to allow the task to run, and whether to restart on failure.
Creating a Basic Scheduled Task
Use the New-ScheduledTask and Register-ScheduledTask cmdlets to create tasks programmatically. This approach is repeatable, scriptable, and produces consistent results across servers.
# Create a simple daily task that runs a PowerShell script at 2:00 AM
$Action = New-ScheduledTaskAction `
-Execute "PowerShell.exe" `
-Argument "-NonInteractive -WindowStyle Hidden -File C:ScriptsDailyCleanup.ps1"
$Trigger = New-ScheduledTaskTrigger -Daily -At "02:00"
$Settings = New-ScheduledTaskSettingsSet `
-ExecutionTimeLimit (New-TimeSpan -Hours 2) `
-RestartCount 3 `
-RestartInterval (New-TimeSpan -Minutes 5) `
-MultipleInstances IgnoreNew
Register-ScheduledTask `
-TaskName "DailyCleanup" `
-TaskPath "MyOrgMaintenance" `
-Action $Action `
-Trigger $Trigger `
-Settings $Settings `
-Description "Daily cleanup script" `
-RunLevel Highest `
-User "SYSTEM"
Running Tasks as a Service Account
For tasks that need elevated privileges or network access, run them as a specific service account. Use the -User and -Password parameters, or configure the task to run whether the user is logged in or not using a stored credential.
# Create a task that runs as a specific domain account
$Credential = Get-Credential "CORPSvcAccount"
Register-ScheduledTask `
-TaskName "DatabaseBackup" `
-TaskPath "MyOrgDatabase" `
-Action (New-ScheduledTaskAction -Execute "PowerShell.exe" -Argument "-File C:ScriptsBackupDB.ps1") `
-Trigger (New-ScheduledTaskTrigger -Daily -At "01:00") `
-Settings (New-ScheduledTaskSettingsSet -ExecutionTimeLimit (New-TimeSpan -Hours 4)) `
-User $Credential.UserName `
-Password $Credential.GetNetworkCredential().Password `
-RunLevel Highest
Creating Event-Triggered Tasks
Tasks can be triggered by Windows Event Log entries, enabling automated responses to system events such as failed services, application errors, or security events.
# Create a task triggered by Event ID 7034 (Service Control Manager - service failed)
$Trigger = New-ScheduledTaskTrigger `
-OnEvent `
-LogName System `
-Source "Service Control Manager" `
-EventId 7034
$Action = New-ScheduledTaskAction `
-Execute "PowerShell.exe" `
-Argument "-NonInteractive -File C:ScriptsServiceFailureAlert.ps1"
Register-ScheduledTask `
-TaskName "ServiceFailureResponse" `
-TaskPath "MyOrgMonitoring" `
-Action $Action `
-Trigger $Trigger `
-User "SYSTEM" `
-RunLevel Highest `
-Description "Responds to service failure events"
Creating Multiple Triggers on a Single Task
A task can have multiple triggers. For example, run a cleanup script both on startup and daily at midnight.
# Create two triggers
$TriggerStartup = New-ScheduledTaskTrigger -AtStartup
$TriggerDaily = New-ScheduledTaskTrigger -Daily -At "00:00"
$Action = New-ScheduledTaskAction -Execute "PowerShell.exe" `
-Argument "-NonInteractive -File C:ScriptsInitialize.ps1"
Register-ScheduledTask `
-TaskName "SystemInitialise" `
-Action $Action `
-Trigger @($TriggerStartup, $TriggerDaily) `
-User "SYSTEM" `
-RunLevel Highest
Configuring Task Settings
Task settings control reliability and resource behaviour. Configure execution time limits, restart behaviour on failure, and priority settings.
# Advanced settings configuration
$Settings = New-ScheduledTaskSettingsSet `
-ExecutionTimeLimit (New-TimeSpan -Hours 1) `
-RestartCount 3 `
-RestartInterval (New-TimeSpan -Minutes 10) `
-MultipleInstances Queue `
-Priority 7 `
-StopIfGoingOnBatteries $false `
-DisallowStartIfOnBatteries $false `
-WakeToRun $false `
-RunOnlyIfNetworkAvailable $false `
-IdleStopTimeout (New-TimeSpan -Minutes 10) `
-DeleteExpiredTaskAfter "PT0S"
# MultipleInstances options:
# IgnoreNew - do not start a new instance if already running
# Parallel - start new instance in parallel
# Queue - queue new instance, start when current completes
# StopExisting - stop the current instance and start a new one
Managing Scheduled Tasks
# List all scheduled tasks
Get-ScheduledTask | Select-Object TaskName, TaskPath, State | Format-Table -AutoSize
# List tasks in a specific folder
Get-ScheduledTask -TaskPath "MyOrgMaintenance" | Select-Object TaskName, State
# Get detailed task information
Get-ScheduledTask -TaskName "DailyCleanup" | Get-ScheduledTaskInfo
# Run a task immediately (regardless of schedule)
Start-ScheduledTask -TaskName "DailyCleanup" -TaskPath "MyOrgMaintenance"
# Stop a running task
Stop-ScheduledTask -TaskName "DailyCleanup" -TaskPath "MyOrgMaintenance"
# Enable or disable a task
Enable-ScheduledTask -TaskName "DailyCleanup" -TaskPath "MyOrgMaintenance"
Disable-ScheduledTask -TaskName "DailyCleanup" -TaskPath "MyOrgMaintenance"
# Delete a task
Unregister-ScheduledTask -TaskName "DailyCleanup" -TaskPath "MyOrgMaintenance" -Confirm:$false
Modifying an Existing Task
# Update the action of an existing task
$Task = Get-ScheduledTask -TaskName "DailyCleanup" -TaskPath "MyOrgMaintenance"
$NewAction = New-ScheduledTaskAction `
-Execute "PowerShell.exe" `
-Argument "-NonInteractive -File C:ScriptsNewCleanup.ps1"
$Task.Actions = @($NewAction)
Set-ScheduledTask -InputObject $Task
# Update the trigger
$NewTrigger = New-ScheduledTaskTrigger -Daily -At "03:00"
Set-ScheduledTask -TaskName "DailyCleanup" -TaskPath "MyOrgMaintenance" -Trigger $NewTrigger
Checking Task Execution Results
# View last run result for a task
Get-ScheduledTaskInfo -TaskName "DailyCleanup" -TaskPath "MyOrgMaintenance" |
Select-Object LastRunTime, LastTaskResult, NextRunTime
# LastTaskResult of 0 = success
# 0x41301 = task is currently running
# 0x1 = incorrect function called / incorrect parameters
# Find tasks that failed in the last 24 hours
Get-ScheduledTask | Get-ScheduledTaskInfo |
Where-Object { $_.LastRunTime -gt (Get-Date).AddHours(-24) -and $_.LastTaskResult -ne 0 } |
Select-Object TaskName, LastRunTime, LastTaskResult
Managing Tasks on Remote Servers
# Manage scheduled tasks on a remote server
$Session = New-PSSession -ComputerName "WEBSVR01" -Credential (Get-Credential "CORPAdmin")
Invoke-Command -Session $Session -ScriptBlock {
# Register the task on the remote server
$Action = New-ScheduledTaskAction -Execute "PowerShell.exe" -Argument "-File C:ScriptsMaintenance.ps1"
$Trigger = New-ScheduledTaskTrigger -Daily -At "03:00"
Register-ScheduledTask -TaskName "RemoteMaintenance" -Action $Action -Trigger $Trigger -User "SYSTEM" -RunLevel Highest
Write-Host "Task registered on $env:COMPUTERNAME"
}
Remove-PSSession $Session
Conclusion
Windows Server 2019 Scheduled Tasks provide a reliable, feature-rich automation framework for running maintenance scripts, backup jobs, monitoring checks, and application tasks on a schedule or in response to events. The PowerShell ScheduledTasks module enables complete programmatic lifecycle management of tasks — creation, modification, execution monitoring, and deletion — making task automation fully scriptable and repeatable across server fleets. Combining event-triggered tasks with notification scripts enables automated responses to system conditions without third-party monitoring tools.