Windows Scheduled Task Forensics: The Complete Guide
Scheduled task forensics end to end: task XML files, the TaskCache registry key, legacy .job files and event logs, and how to correlate them in a case.
TL;DR. A Windows scheduled task leaves up to four kinds of evidence: an XML definition in C:\Windows\System32\Tasks, a registry copy in the SOFTWARE hive under TaskCache, sometimes a legacy .job file in C:\Windows\Tasks, and event log records (Security 4698 to 4702, TaskScheduler/Operational 106, 140, 141, 200, 201). Collect all of them, correlate XML with registry by task path, compare them, and treat each suspicious attribute as a lead to verify rather than a verdict.
Scheduled tasks are one of the most common persistence mechanisms on Windows. MITRE ATT&CK tracks them as T1053.005 Scheduled Task, used for persistence, execution and privilege escalation. They are also one of the noisiest places on a clean system: a fresh Windows 11 install registers well over a hundred Microsoft tasks. The investigator's job is to find the handful that do not belong, and to date them.
This guide is the entry point of the series. Each section links to a deeper article.
The four sources of evidence
| Source | Location | What it gives you | Deep dive |
|---|---|---|---|
| Task XML | C:\Windows\System32\Tasks\<folder>\<name> (no extension) | Full definition: author, registration date, triggers, principal, settings, actions | Task XML anatomy |
| TaskCache | HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache | Tree (names, Id, Index, SD), Tasks (path, hash, actions, triggers, run times) | TaskCache registry forensics |
Legacy .job | C:\Windows\Tasks\*.job | Binary Task Scheduler 1.0 jobs, last run time | .job file forensics |
| Event logs | Security.evtx, Microsoft-Windows-TaskScheduler%4Operational.evtx | Who registered, updated or deleted a task, and when it ran | This article, below |
The XML schema is documented by Microsoft in the Task Scheduler Schema reference. The registry layout and the .job format are partly documented: the .job format is specified in MS-TSCH, while the binary values in TaskCache are known mostly from community reverse engineering, notably the cyber.wtf TaskCache analysis and libyal's winreg-kb.
Where each file lives on every Windows version, and how to collect it without losing data, is covered in where scheduled tasks are stored and how to acquire them.
Why the registry matters as much as the XML
Many checklists stop at the XML folder. That is not enough. The Task Scheduler service keeps its own copy of every registered task in the TaskCache key of the SOFTWARE hive, split in two:
Tree\<task path>holds one key per task, named like the task, with anId(the task GUID), anIndexand anSDvalue, the security descriptor that controls who can see and change the task.Tasks\{GUID}holds the task data:Path,URI,Author,Date,Hash,Actions,TriggersandDynamicInfo, a binary value with the task's creation, last run and last result.
Three consequences for an investigation:
- Deleting the XML file does not unregister the task. The registry entry, and often the task itself, remains. A task present only in TaskCache is worth a close look.
- Removing the
SDvalue hides the task fromschtasks /queryand the Task Scheduler console. This is the technique Microsoft described for the Tarrask malware in April 2022. See Tarrask and hidden scheduled tasks. - The registry holds execution metadata the XML lacks.
DynamicInforecords when the task was created and last run, and the last result code, which the XML never does.
Time, and the trap in the XML
The Date in RegistrationInfo and the StartBoundary of triggers are XML dateTime values. Microsoft's API accepts a UTC offset (YYYY-MM-DDTHH:MM:SS(+-)HH:MM, see Trigger.StartBoundary), but tasks created through the console or schtasks usually store no offset at all: the value is in the machine's local time. Microsoft's own event 4698 example shows it: the event is logged at 2015-09-23T02:03:06Z while the embedded task XML says <Date>2015-09-22T19:03:06.9258653</Date>, seven hours earlier, on a machine in a UTC-7 zone.
TaskCache timestamps (DynamicInfo, key last-write times) are FILETIMEs in UTC. Comparing both for the same task is the simplest way to infer the machine's offset. More on this in task XML anatomy and the StartBoundary glossary entry.
Event logs: useful when they exist
| Log | Event ID | Meaning | Notes |
|---|---|---|---|
| Security | 4698 | Scheduled task created | Contains the full task XML (Microsoft Learn) |
| Security | 4699 | Task deleted | |
| Security | 4700 / 4701 | Task enabled / disabled | |
| Security | 4702 | Task updated | |
| TaskScheduler/Operational | 106 | Task registered | Task name and registering user, no definition |
| TaskScheduler/Operational | 140 | Task updated | |
| TaskScheduler/Operational | 141 | Task deleted | |
| TaskScheduler/Operational | 200 / 201 | Action started / completed | Proof the task actually ran |
The Security events require the Audit Other Object Access Events subcategory, which is not enabled by default on most workstations. The Operational channel is the one behind the "Enable All Tasks History" switch in the Task Scheduler console; on many systems it is off or short-lived. Treat missing events as "not recorded", not "did not happen". Researchers have also shown that tasks written straight into the registry can avoid both 4698 and 106 entirely (Binary Defense). If you have the logs, parse them with the EVTX parser and line them up with the task data.
What to look for
A short list, detailed in how to detect malicious scheduled tasks:
- Commands in user-writable folders:
C:\Users\Public,C:\ProgramData,%TEMP%,AppData. - Encoded PowerShell (
-EncodedCommand) and script hosts or LOLBins such asrundll32,regsvr32,mshta,certutil. - Non-Microsoft tasks running as SYSTEM or with
HighestAvailable. - Tasks at the root of the library or with random-looking names, a pattern Microsoft's own monitoring guidance calls out.
- Hidden tasks (
<Hidden>true</Hidden>) from a non-Microsoft author, and TaskCache entries with no SD value. - Mismatches: XML present but no registry entry, registry entry with no XML, or a
Hashthat does not match the XML on disk. - Recent registration dates close to the incident window.
Each item has innocent explanations. Vendor updaters live in ProgramData; IT scripts use -EncodedCommand. The flags narrow the search; your corroboration decides.
A workflow that holds up
- Acquire
C:\Windows\System32\Tasks(recursive),C:\Windows\SysWOW64\Tasks,C:\Windows\Tasks, the SOFTWARE hive with its.LOG1/.LOG2transaction logs, and the Security and TaskScheduler/Operational logs. KAPE'sScheduledTasksandRegistryHivesSystemtargets cover the files and hives (KapeFiles). - Parse XML,
.joband TaskCache together, and correlate each XML file with its TaskCache entry by task path. - Check integrity: tasks only in the registry, only on disk, missing SD, hash mismatches, and whether the hive was dirty when copied.
- Normalise time: infer or set the UTC offset for zoneless XML times; keep registry FILETIMEs in UTC.
- Triage with the suspicious-attribute list above, then corroborate with process execution evidence (Prefetch, Amcache) and event logs.
The Scheduled Tasks Parser does steps 2 to 4 in the browser: drop the folders, the hive or a KAPE/Velociraptor ZIP, and it correlates XML with TaskCache, checks hashes, flags hidden and registry-only tasks, and exports CSV or JSON. Nothing is uploaded. The walkthrough is in how to analyze scheduled tasks in your browser.
FAQ
Where does Windows store scheduled tasks?
In three places: an XML definition per task under C:\Windows\System32\Tasks, a registry copy under HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache, and, for legacy tasks only, binary .job files in C:\Windows\Tasks.
Is the XML file or the registry the source of truth?
On Windows 8 and later the Task Scheduler service works from the TaskCache registry data; the XML files are kept in step with it. A task can survive in the registry after its XML file is deleted, so always collect and compare both.
Which event IDs record scheduled task creation?
Security 4698 (created, with the full task XML), 4699 (deleted), 4700 (enabled), 4701 (disabled) and 4702 (updated), which need the Audit Other Object Access Events policy; and TaskScheduler/Operational 106 (registered), 140 (updated), 141 (deleted), 200 (action started) and 201 (action completed).
Further reading
- Microsoft Learn, Task Scheduler Schema.
- Microsoft, [MS-TSCH]: Task Scheduler Service Remoting Protocol.
- Microsoft Threat Intelligence, Tarrask malware uses scheduled tasks for defense evasion (April 2022).
- cyber.wtf, Windows Registry Analysis: Tasks (2022).
- MITRE ATT&CK, T1053.005 Scheduled Task.