Skip to main content

Windows Scheduled Tasks

This guide explains how to automate tasks on your Windows VPS with Task Scheduler.

Access Task Scheduler

  • Win + R > taskschd.msc
  • Or search for "Task Scheduler"

Create a Simple Task

Via GUI

  1. In the right panel, click Create Basic Task...
  2. Name: Give a descriptive name
  3. Trigger: Choose the frequency
    • Daily, Weekly, Monthly, etc.
  4. Action: Select Start a program
  5. Program/script: Path to the executable or script
  6. Finish

Example: Daily Backup

  1. Name: "Daily Backup"
  2. Trigger: Daily at 03:00
  3. Action: C:\Scripts\backup.bat

Create an Advanced Task

For more options, use Create Task...

General Tab

  • Name: Task name
  • Run whether user is logged on or not: Check for server tasks
  • Run with highest privileges: For tasks requiring admin rights

Triggers Tab

Click New... to add triggers:

  • On a schedule: Fixed time
  • At startup: When the server starts
  • At log on: When a user logs in
  • On an event: In response to a Windows event

Actions Tab

  • Start a program: Run a script or application
  • Send an e-mail: (deprecated, use a PowerShell script)
  • Display a message: (deprecated)

Conditions Tab

  • Start the task only if the computer is idle
  • Start only if on AC power
  • Wake the computer to run this task

Settings Tab

  • Allow task to be run on demand
  • Run task as soon as possible after a scheduled start is missed
  • Stop the task if it runs longer than: Timeout

PowerShell: Task Management

Create a Task

# Define the action
$action = New-ScheduledTaskAction -Execute "PowerShell.exe" -Argument "-File C:\Scripts\backup.ps1"

# Define the trigger (every day at 3 AM)
$trigger = New-ScheduledTaskTrigger -Daily -At 3am

# Define settings
$settings = New-ScheduledTaskSettingsSet -ExecutionTimeLimit (New-TimeSpan -Hours 1)

# Create the task
Register-ScheduledTask -TaskName "Daily Backup" -Action $action -Trigger $trigger -Settings $settings -User "SYSTEM" -RunLevel Highest

Trigger Examples

# At system startup
$trigger = New-ScheduledTaskTrigger -AtStartup

# Every hour
$trigger = New-ScheduledTaskTrigger -Once -At (Get-Date) -RepetitionInterval (New-TimeSpan -Hours 1) -RepetitionDuration (New-TimeSpan -Days 365)

# Every Monday at 8 AM
$trigger = New-ScheduledTaskTrigger -Weekly -DaysOfWeek Monday -At 8am

# 1st of every month
$trigger = New-ScheduledTaskTrigger -Monthly -DaysOfMonth 1 -At 00:00

Manage Existing Tasks

# List all tasks
Get-ScheduledTask

# View task details
Get-ScheduledTask -TaskName "Daily Backup" | Get-ScheduledTaskInfo

# Run a task manually
Start-ScheduledTask -TaskName "Daily Backup"

# Disable a task
Disable-ScheduledTask -TaskName "Daily Backup"

# Enable a task
Enable-ScheduledTask -TaskName "Daily Backup"

# Delete a task
Unregister-ScheduledTask -TaskName "Daily Backup" -Confirm:$false

Useful Scripts

Backup Script

Create C:\Scripts\backup.ps1:

# Configuration
$source = "C:\inetpub\wwwroot"
$destination = "C:\Backups"
$date = Get-Date -Format "yyyy-MM-dd_HH-mm"
$backupFile = "$destination\backup_$date.zip"

# Create destination folder if needed
if (!(Test-Path $destination)) {
New-Item -ItemType Directory -Path $destination
}

# Create archive
Compress-Archive -Path $source -DestinationPath $backupFile -Force

# Delete backups older than 7 days
Get-ChildItem $destination -Filter "*.zip" | Where-Object { $_.LastWriteTime -lt (Get-Date).AddDays(-7) } | Remove-Item

# Log
Add-Content -Path "C:\Scripts\backup.log" -Value "$(Get-Date): Backup created - $backupFile"

Service Restart Script

# C:\Scripts\restart-service.ps1
$serviceName = "MyService"

Stop-Service -Name $serviceName -Force
Start-Sleep -Seconds 5
Start-Service -Name $serviceName

# Log
$status = Get-Service -Name $serviceName
Add-Content -Path "C:\Scripts\service.log" -Value "$(Get-Date): $serviceName - $($status.Status)"

Log Cleanup Script

# C:\Scripts\cleanup-logs.ps1
$logFolders = @(
"C:\inetpub\logs\LogFiles",
"C:\Windows\Temp"
)
$daysToKeep = 30

foreach ($folder in $logFolders) {
Get-ChildItem $folder -Recurse -File | Where-Object {
$_.LastWriteTime -lt (Get-Date).AddDays(-$daysToKeep)
} | Remove-Item -Force
}

Add-Content -Path "C:\Scripts\cleanup.log" -Value "$(Get-Date): Cleanup completed"

Disk Monitoring Script

# C:\Scripts\disk-check.ps1
$threshold = 80
$disk = Get-WmiObject Win32_LogicalDisk -Filter "DeviceID='C:'"
$usedPercent = [math]::Round(($disk.Size - $disk.FreeSpace) / $disk.Size * 100)

if ($usedPercent -gt $threshold) {
# Send an alert email
$smtpServer = "smtp.example.com"
$from = "server@example.com"
$to = "admin@example.com"
$subject = "VPS Disk Alert"
$body = "Drive C: is at $usedPercent% capacity."

Send-MailMessage -SmtpServer $smtpServer -From $from -To $to -Subject $subject -Body $body
}

Common Use Cases

Restart a Game Server Every 6 Hours

$action = New-ScheduledTaskAction -Execute "PowerShell.exe" -Argument "-Command Restart-Service -Name 'FiveM'"
$trigger = New-ScheduledTaskTrigger -Once -At (Get-Date) -RepetitionInterval (New-TimeSpan -Hours 6) -RepetitionDuration ([TimeSpan]::MaxValue)
Register-ScheduledTask -TaskName "Restart FiveM" -Action $action -Trigger $trigger -User "SYSTEM" -RunLevel Highest

Run a Script at Startup

$action = New-ScheduledTaskAction -Execute "PowerShell.exe" -Argument "-File C:\Scripts\startup.ps1"
$trigger = New-ScheduledTaskTrigger -AtStartup
$settings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries
Register-ScheduledTask -TaskName "Startup Script" -Action $action -Trigger $trigger -Settings $settings -User "SYSTEM" -RunLevel Highest

View Execution Logs

# Task history
Get-ScheduledTask -TaskName "Daily Backup" | Get-ScheduledTaskInfo

# View in Event Viewer
eventvwr.msc
# Then: Applications and Services Logs > Microsoft > Windows > TaskScheduler > Operational

Troubleshooting

Task Doesn't Run

  1. Verify the user has permissions
  2. Check "Run whether user is logged on or not"
  3. Verify paths (use absolute paths)
  4. Check Event Viewer

Error 0x1

The script ended with an error. Test the script manually.

"Access Denied" Error

Run with highest privileges and/or use the SYSTEM account.

Tip

Always test your scripts manually before scheduling them, and use log files to track their execution.