Skip to content

.job File Forensics: Legacy Tasks in C:\Windows\Tasks

How to read legacy .job files: the MS-TSCH fixed and variable sections, triggers, the local-time last run SYSTEMTIME, and when .job files still appear on modern Windows.

Published on 5 min read

TL;DR. .job files are the Task Scheduler 1.0 format, in C:\Windows\Tasks. Microsoft specifies them in MS-TSCH: a 68-byte fixed section (versions, job UUID, priority, status, flags, last run time as a SYSTEMTIME) and a variable section (command, parameters, working directory, author, comment, triggers). They are rare on modern Windows, which is exactly why one showing up there deserves attention.

This article belongs to the fundamentals series that starts with the scheduled task forensics guide.

Where .job files come from

EraPrimary task store.job files
Windows 2000, XP, Server 2003C:\Windows\Tasks\*.jobEvery task
Vista, 7, Server 2008 (R2)XML in System32\Tasks + TaskCacheTasks created through the 1.0 API or at.exe can also get a .job for compatibility
Windows 8 and laterXML + TaskCacheUncommon; at.exe is deprecated in favour of schtasks

The Cyber Triage overview describes the same progression. On a Windows 10 or 11 machine, a .job file therefore means one of: a very old application still using the 1.0 interface, a leftover from an in-place upgrade, or deliberate use of legacy tooling. None of those is malicious by itself; all of them are worth explaining.

The KapeFiles ScheduledTasks target collects C:\Windows\Tasks\*.job and the Windows.old equivalent, together with SchedLgU.txt, the 1.0 scheduler's text log.

The fixed-length section

MS-TSCH names it FIXDLEN_DATA. libyal's Job file format documentation lays it out as 68 bytes:

OffsetSizeFieldForensic use
02Product versionOS that wrote the file (e.g. 0x0501 XP, 0x0600 Vista, 0x0a00 Windows 10)
22File format version
416Job UUIDUnique per job
202Application name offsetWhere the variable section starts
222Triggers offset
244Error retry count and interval
284Idle deadline and wait
324Priority classNormal, high, idle, realtime
364Maximum run time (ms)
404Exit codeLast exit code of the program
444StatusReady, running, disabled, has not run...
484FlagsIncludes disabled and hidden bits
5216Last run timeSYSTEMTIME

The product version is a quick provenance check: a .job file on a Windows 10 machine whose product version says XP was probably copied from elsewhere rather than created locally.

The last run time

The last run time is a SYSTEMTIME (year, month, day of week, day, hour, minute, second, millisecond), not a FILETIME. It carries no time zone. It is generally treated as local time, and libyal's documentation explicitly marks that as still to be confirmed. Record it as stored, state the assumption, and corroborate with another source before building a timeline on it. A zero value means the job has never run.

The variable-length section

After the fixed section come, in order:

  1. Running instance count.
  2. Application name (the command), length-prefixed UTF-16.
  3. Parameters.
  4. Working directory.
  5. Author.
  6. Comment.
  7. User data and reserved data (opaque blobs).
  8. Triggers: a count, then fixed-size trigger records with start date, end date, start time, duration, interval, flags and a type (once, daily, weekly, monthly, on idle, at startup, at logon).
  9. Optionally a job signature.

Triggers store dates as separate year, month and day words, without time zone. Same caveat as above: local time by convention.

Reading a .job file in practice

What the Scheduled Tasks Parser extracts from each .job file: the command, parameters, working directory, author, comment, flags (disabled, hidden), status, exit code, the triggers with their start and end dates, and the last run time as stored, labelled as local. The .job rows appear alongside XML and TaskCache tasks, and are flagged as legacy actions so they stand out on a modern system.

Questions to ask of each file:

  • Is the command in a user-writable path? Same rule as for XML tasks, see detecting malicious scheduled tasks.
  • Does the author match a real account? Like the XML Author, it is free text.
  • Is there a matching XML task? On Vista and 7, a job registered through the compatibility layer should have one. A .job with no XML or TaskCache entry was not registered by the current service, or was cleaned up partially.
  • Do the file system timestamps agree? The $MFT times of the .job file, and of C:\Windows\Tasks itself, bracket its creation and last modification. The scheduler updates the file when the job runs, so the modification time often follows the last run time. A USN journal can show when the file was created or deleted.

Legacy tooling and modern detections

at.exe still exists on current Windows for backward compatibility but is deprecated; Microsoft points to schtasks instead. Seeing at.exe in process execution evidence (Prefetch, Amcache) on a modern workstation is uncommon, and should lead you to check C:\Windows\Tasks and the TaskCache for At1-style task names.

FAQ

What is a .job file?

A binary scheduled task file used by Task Scheduler 1.0, stored in C:\Windows\Tasks. Microsoft documents the format in MS-TSCH as a fixed-length section followed by a variable-length section with the command, arguments, author, comment and triggers.

Do Windows 10 and 11 still use .job files?

Rarely. Modern tasks are XML plus TaskCache. A .job file can still appear for tasks registered through the legacy Task Scheduler 1.0 interfaces or the deprecated at command, and on systems upgraded from old versions. Collect C:\Windows\Tasks anyway.

Is the last run time in a .job file UTC?

It is stored as a SYSTEMTIME structure with no time zone information, generally understood to be local time. libyal's documentation still marks this as to be confirmed, so corroborate before relying on it.

Related articles

Step by step: load task XML, .job files and the SOFTWARE hive into a free in-browser parser, read hidden and registry-only tasks, fix time zones and export. With a fictional case.
A practical checklist to spot malicious scheduled tasks: user-writable paths, encoded PowerShell, LOLBins, SYSTEM principals, random names, hidden tasks and XML/registry mismatches.
What the TaskCache key in the SOFTWARE hive stores for each scheduled task: Tree Id/Index/SD, Tasks values, DynamicInfo run times, Actions and Triggers blobs, and the Hash.