Windows Task Scheduler: Advanced Triggers, Conditions and Hidden Tasks

5 min read

Advanced Windows Task Scheduler configuration. Event-based triggers, conditions, run-on-demand without UAC, find hidden tasks and debug failed scheduled jobs.

Share:TelegramX

Beyond basic scheduling, Task Scheduler has powerful trigger types and execution conditions that most admins never use.


Event-Based Triggers

Run a task when a specific event appears in Event Log:

# Trigger on failed logon attempt (Event ID 4625)
$trigger = New-ScheduledTaskTrigger -OnEvent `
  -Subscription '<QueryList><Query><Select Path="Security">*[System[EventID=4625]]</Select></Query></QueryList>' `
  -Delay "00:01:00"  # wait 1 minute after event

$action = New-ScheduledTaskAction -Execute "powershell.exe" `
  -Argument '-Command "Send-MailMessage -To admin@company.com -Subject \"Failed Login Detected\" -From server@company.com -SmtpServer smtp.company.com"'

Register-ScheduledTask -TaskName "Alert-FailedLogin" `
  -Action $action -Trigger $trigger -RunLevel Highest

# Trigger on new USB device connected (Event ID 2003)
$trigger = New-ScheduledTaskTrigger -OnEvent `
  -Subscription '<QueryList><Query><Select Path="Microsoft-Windows-DriverFrameworks-UserMode/Operational">*[System[EventID=2003]]</Select></Query></QueryList>'

Idle and Workload Conditions

# Only run when PC has been idle for 10 minutes
$settings = New-ScheduledTaskSettingsSet `
  -RunOnlyIfIdle `
  -IdleDuration "00:10:00" `
  -IdleWaitTimeout "04:00:00"  # wait up to 4 hours for idle

# Stop if PC wakes from idle
$settings = New-ScheduledTaskSettingsSet `
  -RunOnlyIfIdle -StopIfGoingOffIdle

# Only run on AC power
$settings = New-ScheduledTaskSettingsSet -RunOnlyIfNetworkAvailable

Register-ScheduledTask -TaskName "IdleTask" `
  -Action $action -Trigger $trigger -Settings $settings

Run Without UAC Prompt

# Run as SYSTEM (no UAC, no user required)
$principal = New-ScheduledTaskPrincipal `
  -UserId "NT AUTHORITY\SYSTEM" `
  -LogonType ServiceAccount `
  -RunLevel Highest

Register-ScheduledTask -TaskName "SilentAdminTask" `
  -Action $action -Trigger $trigger -Principal $principal

Find and Audit Hidden Tasks

Malware often creates tasks in unusual locations:

# Tasks in root (user-created) — most legitimate tasks
Get-ScheduledTask | Where-Object {$_.TaskPath -eq "\"} |
  Select-Object TaskName, State, @{n='Action';e={$_.Actions.Execute}}

# Tasks NOT in \Microsoft\ paths
Get-ScheduledTask | Where-Object {$_.TaskPath -notlike "*\Microsoft\*"} |
  Select-Object TaskPath, TaskName, @{n='Action';e={$_.Actions.Execute}}

# Tasks running from temp or user profile (suspicious)
Get-ScheduledTask | Where-Object {
  $_.Actions.Execute -like "*\Temp\*" -or
  $_.Actions.Execute -like "*\AppData\*" -or
  $_.Actions.Execute -like "*\Users\*"
} | Select-Object TaskName, @{n='Executable';e={$_.Actions.Execute}}

Task History and Debugging

# Enable history if disabled
wevtutil sl Microsoft-Windows-TaskScheduler/Operational /e:true

# View recent task runs (all tasks)
Get-WinEvent -LogName "Microsoft-Windows-TaskScheduler/Operational" -MaxEvents 50 |
  Where-Object {$_.Id -in @(100,101,102,103,200,201)} |
  Select-Object TimeCreated, Id,
    @{n='Task';e={$_.Properties[0].Value}},
    @{n='Result';e={$_.Properties[1].Value}} |
  Format-Table -AutoSize

# Why did a task fail?
Get-ScheduledTaskInfo -TaskName "DailyScript" |
  Select-Object LastRunTime, LastTaskResult, NextRunTime

# Task result codes
# 0x0 = Success
# 0x1 = Incorrect function
# 0x41301 = Still running
# 0x41303 = Not yet run
# 0x41306 = Task stopped

Disable/Pause All Tasks (Emergency)

# Disable all non-Microsoft tasks
Get-ScheduledTask | Where-Object {$_.TaskPath -notlike "*\Microsoft\*"} |
  Disable-ScheduledTask

# Re-enable
Get-ScheduledTask | Where-Object {$_.TaskPath -notlike "*\Microsoft\*"} |
  Enable-ScheduledTask

Summary

Event triggers with <QueryList> XML. Idle conditions with -RunOnlyIfIdle. Run silently as SYSTEM with SYSTEM principal. Audit all non-Microsoft tasks for malware. Enable history with wevtutil sl for debugging. Result 0x0 = success.

Frequently Asked Questions

My task shows LastTaskResult 0x1 — what does that mean?

0x1 = the PowerShell/batch script returned exit code 1. Usually means the script encountered an error. Add -ErrorAction Stop and proper error handling to get useful exit codes.

Task runs fine manually but fails on schedule — common causes?

  1. Working directory wrong — use full paths in scripts
  2. Environment variables different for SYSTEM vs user
  3. Missing modules — add explicit Import-Module in the script
  4. Network drives not available when SYSTEM runs
  5. Execution policy — add -ExecutionPolicy Bypass to the PowerShell action

Can I run a scheduled task under a user account without that user being logged in?

Yes — set logon type to Password and provide credentials. The account needs "Log on as batch job" right: secpol.msc → Local Policies → User Rights Assignment.

Related articles

💬 Leave a comment

Comments are moderated before publishing.

← All articles