MENASEC

Scheduled tasks for persistence and remote execution: what to log, what to alert on

A scheduled task is two detections wearing one name. One is quiet persistence that survives reboots; the other is a remote-execution hop that plants a task over the network. Different telemetry, different tuning, one technique ID.

MENASEC Published 29 Jun 2026

A scheduled task is really two detections sharing one name, and if you build a single rule for both you will do neither well. On one side is persistence: a task that quietly reinstalls a foothold every time the machine boots or the user logs in. On the other is remote execution: an operator on one box creating a task on another to run a command there, which is a lateral-movement hop dressed up as routine administration. Both are T1053.005 in ATT&CK. They look different in the telemetry, so we treat them as two rules that happen to share a technique ID.

The events you actually need

Before either detection works you need the right events turned on, and the default audit policy will not give them to you. The Security log carries a small family of scheduled-task events once you enable the Other Object Access auditing subcategory: 4698 for a task created, 4699 for one deleted, 4700 and 4701 for enabled and disabled, and 4702 for a task updated. The one that earns its keep is 4698, because its event data includes the full task definition as XML, which means the command the task will run, its arguments, and its trigger are all right there in the record. That is a gift for detection. You do not have to go pull the task file off disk; the action is in the log.

Alongside the Security log, the Microsoft-Windows-TaskScheduler/Operational channel records the task lifecycle from the scheduler’s own point of view, with event 106 when a task is registered and 140 when it is updated. We forward both channels through Windows Event Forwarding into QRadar off Server 2022 domain controllers and members. Microsoft’s event 4698 reference documents the XML layout if you are writing the parser that pulls the command and trigger out of the record.

Persistence: the task that should not be there

For the persistence case, 4698 is the anchor and the tuning lives entirely in the task definition. We read the embedded action out of the XML and judge it the same way we judge any autostart: where does the command point, and who wrote it. A task whose action is a signed binary in Program Files, created by an installer, is noise. A task whose action is powershell.exe with an encoded command, a script in a user temp directory, or a LOLBIN such as mshta.exe or rundll32.exe, is a lead. Triggers matter too, because a task set to run at logon or at boot with a hidden flag is exactly the shape of persistence and almost never the shape of legitimate scheduled maintenance, which tends to run on a calendar.

Remote execution: the task created over the wire

The remote-execution case has a different fingerprint, and it is the more interesting hunt. When an operator creates a task on a remote host, whether through schtasks /s, an Impacket-style atexec, or any tool that drives the task scheduler over the network, the request travels over SMB to the ATSVC RPC interface, which is a named pipe called atsvc. So on the target you see a sequence, not a single event: a 4624 type 3 network logon, then a 4698 whose creator is that same network-logon account, and the task action running under the Schedule service. If you collect Sysmon Event ID 18, pipe connected, you catch the atsvc pipe access directly, and 5145, a network share object being accessed, gives you the same story from the file-share auditing side. A task creation that arrives immediately after a network logon, from a remote account, is remote execution until proven otherwise. Local persistence does not carry that network-logon prefix, which is how the two cases separate cleanly in the data.

Sysmon fills the command-line hole

The Security events tell you a task was created and what it claims it will do. Sysmon tells you what actually ran. When a task fires, the Schedule service, hosted inside an svchost.exe launched with the netsvcs group, spawns the action, so Sysmon Event ID 1 shows the task’s process with svchost.exe as its parent and the Schedule service in the chain. That parent relationship is a reliable pivot: find the svchost -k netsvcs children that are shells, script hosts, or LOLBINs, and you have caught the execution even where audit policy for the Security events was incomplete. We run Sysmon 15 across the same estate, which means most task activity shows up twice, once as a 4698 registration and once as a Sysmon process create when it runs, and having both halves makes the timeline argument for an analyst much shorter.

Where we draw the false-positive line

Scheduled tasks are a normal part of how Windows and third-party software operate, so the false-positive surface is wide and you have to respect it. Updaters create tasks, and you will recognize them: the browser updater, the office-suite updater, GPU and driver maintenance, backup and configuration-management agents. These come from known creators, land in predictable task-folder paths, and carry signed actions in standard directories. The tuning that holds up is to exclude those known task names, paths, and creators once, then judge the residue by action content and by whether a network logon preceded the creation. This catches most of the abuse, not all, because a careful operator can name a task to blend in and point it at a plausible path, which is why we do not rely on names alone and keep the action-content rule and the remote-creation rule running underneath the allowlist.

The remote-creation half of this shares its plumbing with a lot of other lateral movement, because the named pipe is the transport. If you are instrumenting pipe activity for this, the same telemetry feeds the named-pipe pivoting writeup, and the way we correlate a remote task with the logon and service activity around it follows the same model as the 2026 lateral-movement detection. The schtasks command reference is worth a read for the exact flags an operator has to pass, because those flags end up in the command lines your rules are matching on.

threat-huntingpersistencelateral-movementdetection-engineeringwindows-event-log