Skip to content

Repository files navigation

OfflineTasks

Finish Windows maintenance at the one moment it always works: before the desktop and third-party software start. OfflineTasks runs small, declarative cleanup jobs right after a reboot — when files are closed, nothing is in use, and tidy-up work completes in seconds instead of fighting a live system.

Built for system administrators and helpdesks who do housekeeping on many machines and want it predictable, logged, and hands-off.

Typical uses:

  • finish uninstalling applications that leave files and folders behind;
  • clean up folders that report in use or access denied while Windows is running;
  • remove orphaned service registrations and stale vendor registry keys;
  • run a silent MSI uninstall at a controlled point in the boot cycle.

What it is NOT (read this first)

OfflineTasks is deliberately built so that it cannot be repurposed as malware:

  • No arbitrary command execution. Jobs are declarative JSON with a fixed whitelist of four actions (delete-paths, remove-services, delete-registry, uninstall-product). Each action has hard guards: no drive-qualified paths, no .., system directories are never deletable, critical OS services and registry subtrees are refused.
  • No network. The tool has no listener, no client, no remote control channel of any kind.
  • No stealth. Everything is plain text (PowerShell, JSON), every run writes a human-readable report to C:\OfflineTasks\logs\job-report.txt, and the arming step validates and displays the job before anything happens.
  • No persistence. The startup task / Safe Mode service and every boot modification remove themselves after the run. Nothing survives reboots.

The job file is the entire contract: what you read is what runs.

How it works

Two engines, chosen per job:

engine what happens when to use
startup A SYSTEM scheduled task runs the job right after a normal reboot, then removes itself. If the job asks to remove services, their registrations are already taken care of at arm time, so nothing loads again after the reboot. Default. Uses only Microsoft-signed components (schtasks, PowerShell, sc.exe) — there is no custom binary at all.
safemode A one-shot BCD entry (/bootsequence) boots Safe Mode exactly once; a small open-source service binary runs the job in that minimal environment, then restores normal boot and removes itself. The most stubborn cases, where files stay locked even right after a normal reboot.

The machine always comes back

  • startup: the machine boots normally; the task self-deletes.
  • safemode: the Safe Mode boot entry fires exactly once. Whatever happens after that boot — crash, power loss, job failure — the next boot is plain normal Windows. The sticky safeboot flag is never set on the normal boot entry. A machine cannot be stranded in Safe Mode by design.
  • BitLocker-protected system volumes are refused unless protection is suspended for exactly one boot (-SuspendBitLocker).

Usage

  1. Edit job.json (or copy an example from examples/).
  2. Run OfflineTasks.bat (elevates via UAC). The job is validated first; a bad job is refused whole, nothing is armed.
  3. Confirm the reboot. The job runs unattended and the machine returns to normal Windows by itself.
  4. Read C:\OfflineTasks\logs\job-report.txt.

Dry-run (validate only, change nothing):

.\engine\Install-OfflineJob.ps1 -JobFile .\job.json -DryRun

Cancel an armed-but-not-yet-run job:

.\engine\Install-OfflineJob.ps1 -Disarm

Job format

{
  "description": "Remove a stale application folder",
  "engine": "safemode",
  "steps": [
    { "action": "delete-paths", "volumeLabel": "Local Disk",
      "paths": ["Program Files\\VendorName"] },
    { "action": "remove-services", "names": ["VendorNameService"] },
    { "action": "delete-registry",
      "keys": ["HKLM\\SOFTWARE\\Vendor\\Product"] },
    { "action": "uninstall-product", "productCode": "{GUID}" }
  ]
}
  • delete-paths: paths are relative to the root of the volume found by label (drive letters are intentionally not accepted — they differ between environments; find the label with vol C: or Get-Volume).
  • remove-services: exact service names; a built-in blocklist refuses critical OS services.
  • delete-registry: keys must live under HKLM\SOFTWARE or HKLM\SYSTEM\CurrentControlSet\Services; protected subtrees are refused.
  • uninstall-product: silent msiexec /x {GUID}.

Optional job fields: "backup": false disables the default backup-before-delete; "backupMaxMB": 1024 caps cross-volume backup copies.

Backup before destructive steps (quarantine)

With the default "backup": true, nothing is deleted outright:

  • folders/files on the same volume are moved to C:\OfflineTasks\backup\<timestamp>\ (instant, size-free);
  • cross-volume targets are copied up to backupMaxMB;
  • registry keys and service registrations are exported to .reg files first.

Restore anything with engine\Restore-OfflineBackup.ps1 (interactive pick, moves paths back and re-imports .reg files).

Reports

Every run writes two reports to C:\OfflineTasks\logs\:

  • job-report.txt — human-readable, primary artifact;
  • job-report.json — machine-readable (result: SUCCESS|PARTIAL|FAILED, per-step outcomes, backup locations) for fleet automation; the runner's exit code is 0 on SUCCESS and 1 otherwise.

Building a job interactively

engine\New-OfflineJob.ps1 guides you through a valid job file with live validation (volume labels resolved, paths checked against the guards) — no hand-edited JSON required.

A JSON Schema is provided for editor validation and autocompletion of job files.

Layout

OfflineTasks.bat            launcher (edit job.json first)
job.json                    the work order
engine/
  Install-OfflineJob.ps1    armer: validate, stage, schedule, reboot
  Invoke-OfflineJob.ps1     the runner that executes job steps
bin/otasksvc.exe            Safe Mode service (built from src/, Go, MIT)
src/otasksvc/               service source code
build/Build-Package.ps1     builds the release zip into out/
examples/                   ready-made job files

Antivirus notes

  • The startup engine contains no custom binary at all — only Microsoft-signed components. There is nothing to flag.
  • The safemode service is a small, open-source Go binary with full VERSIONINFO, no packing, no obfuscation; releases are published with SHA-256 hashes. If a vendor still flags it, that is a false positive — please report it to the vendor (and open an issue). Code-signed releases are planned via a free open-source signing program.
  • The whitelist-by-design job format is the main argument in any review: the tool physically cannot execute attacker-supplied commands.

Build from source

Requirements: Go, goversioninfo (go install github.com/josephspurrier/goversioninfo/cmd/goversioninfo@latest).

.\build\Build-Package.ps1     # produces out\OfflineTasks.zip + SHA-256

Code signing

Release binaries are planned to be signed free of charge through the SignPath Foundation open-source code signing program (certificate issued to "SignPath Foundation") - see CODE_SIGNING_POLICY.md. Current releases publish SHA-256 hashes for integrity verification.

Privacy

OfflineTasks collects no data: no telemetry, no network connections of any kind, no identifiers. Jobs run fully offline; reports stay on the local disk.

License

MIT — see LICENSE.

About

Declarative offline maintenance jobs for Windows: run whitelisted cleanup tasks at startup or in a one-shot Safe Mode boot, with hard safety guards. No network, no persistence, no arbitrary command execution.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages