HomeTopicsAutomation Ladder › Automation Debt

The Automation Inventory: Taming Jobs Nobody Remembers

It usually starts with a decommissioning. A server is finally being retired, someone opens its task scheduler as a formality, and there they are: eleven scheduled jobs, four of them transfer scripts, two pointing at partners the company no longer works with, one running as the account of an employee who left years ago — and nobody in the room can say what any of them do, or what breaks if they stop. Every mature estate has a room like this. Most have several.

This article is about draining that swamp and keeping it drained: how automation gets forgotten in the first place, how to hunt down every scheduled and triggered transfer job you actually have, the inventory that records them in a form a stranger can use, the signs that a job is dead or worse, and the careful ritual for retiring jobs without breaking dependencies nobody admitted to. It closes our Automation Ladder series, because this is the truth about the ladder: climbing it creates automation, and automation, left unrecorded, becomes debt.

How Jobs Become Ghosts

No one plans to forget a job. Forgetting is what happens by default, through a lifecycle so consistent it deserves to be written out. A job is born urgent — somebody needed the flow and built it. It works, so attention moves elsewhere. The author changes teams or companies; the documentation, if any, lives in a folder nobody opens. The business process the job served quietly changes — the partner merges, the report is replaced — but nobody connects that change to a scheduled task on a server three rooms away. The job keeps running, because that is the one thing automation is excellent at. Years pass. Now it is a ghost: consuming credentials, moving data, answerable to no one.

Transfer jobs make unusually dangerous ghosts, for three reasons. They hold credentials — keys and passwords that stay valid, sometimes with real permissions on partner systems, long after their purpose expired. They move data across boundaries — a forgotten job can be shipping files out of your network nightly, which is exactly the behavior a security review exists to catch, except nobody knows to review it. And they create dependencies in other organizations — a partner may have built their morning process around a file your ghost delivers, which is how "cleaning up old tasks" becomes an incident with a customer's name on it. The general warning was given at the very start of this series in why automate file transfers; this article is the cure.

The Hunt: Where Automation Hides

You cannot inventory what you have not found, and transfer automation hides in more places than any one scheduler. The hunt is a sweep through every layer, per machine. Budget a surprising amount of time for it; the first sweep of an old estate always finds more than anyone predicted.

Unix-like systems: cron and friends

Per-user crontabs are the classic hiding place, and each user has their own. As root, list them all:

for u in $(cut -d: -f1 /etc/passwd); do
    crontab -l -u "$u" 2>/dev/null | sed "s/^/$u: /"
done

Reading it: cut -d: -f1 /etc/passwd extracts every account name (fields split on :, field 1); crontab -l -u "$u" lists that user's crontab; 2>/dev/null discards the "no crontab for..." noise from accounts that have none; and the sed prefixes each surviving line with the account it belongs to, so the output is self-labeling. Then check the system-wide locations the per-user command does not cover: /etc/crontab, the /etc/cron.d/ directory, and the cron.hourly through cron.monthly folders. Finally, systemd timers are a second scheduler entirely — systemctl list-timers --all shows them, with --all including the inactive ones you would otherwise miss.

Windows: Task Scheduler and beyond

Export every scheduled task with full detail into a spreadsheet-ready file:

schtasks /query /v /fo CSV > C:\audit\tasks_thishost.csv

Here /query lists tasks, /v (verbose) adds the columns that matter for a hunt — the command each task actually runs, the account it runs as, and its last run time and result — and /fo CSV formats the output for import into the inventory spreadsheet. Sweep the whole library, including vendor folders: transfer scripts hide among application maintenance tasks. Then look past Task Scheduler: services that wrap scripts, startup folder entries, and anything a monitoring agent runs on a timer.

The places no scheduler shows

Three hiding spots defeat scheduler-by-scheduler sweeps. Transfer tools' own schedulers: jobs configured inside a transfer-automation product run from that product, not from cron or Task Scheduler — open each tool's task list separately. Application-embedded transfers: business applications that upload their own exports on an internal timer, visible only in their admin screens. The undergrowth: NAS appliances with sync jobs, a workstation under a desk running someone's personal "temporary" script since two managers ago. Ask veterans; folklore is a legitimate discovery tool.

Then flip your perspective: instead of asking machines what they send, ask servers what they receive. The logs of your own transfer servers show every account that connects on a rhythm — and a login that arrives at 03:00 every night is a scheduled job announcing itself, whether or not you found its home. On Windows, a server such as Sysax Multi Server logs session and transfer activity to file and to a database, which makes this rhythm-hunting straightforward: list distinct accounts by hour and the nocturnal regulars stand out. The same server-side approach powers protocol cleanups, and the technique is developed further in finding all your FTP — a sibling inventory problem — and in the file flow census, which maps flows business-first rather than machine-first. Run both directions and reconcile: every rhythmic login should match a job you found, and every mismatch is either a discovery or an intruder. Both are worth knowing about.

The Inventory: Columns That Earn Their Place

The inventory itself should be boring technology — a spreadsheet or a wiki table is genuinely fine. What matters is the columns, and the test each column must pass: would this cell help a stranger, at 03:00, during an incident, decide what this job is and whether it may be stopped? The working set:

  • Job name — as it appears in its scheduler, so it can be found again.
  • What it moves — file pattern, source, destination, direction. The business payload, not just paths.
  • Trigger — schedule ("02:10 weekdays") or event ("on arrival in inbox/").
  • Runs on / runs as — host name and account. The account column is where ghost jobs glow: anything running as a departed employee or a shared admin login is a finding in itself, per service account hygiene.
  • Credential — what kind (key, password), where stored, and when it expires. Expiring credentials are the most common way forgotten jobs finally fail.
  • Owner — a team, with a named contact. "IT" is not an owner; owners answer questions.
  • Purpose — one sentence a business person would recognize: "daily invoices to ACME for their morning billing run."
  • Last verified — when a human last confirmed the job runs and its output is consumed.
  • Status — active, suspect, retiring, or retired (with the date words like "retired after Mar review").

Here is the structure in action, with the kind of rows a real first sweep produces — including the uncomfortable ones, which are the entire point:

Job / trigger What it moves Runs on / as Owner Status
acme-daily-report
cron, 02:10 weekdays
report_YYYYMMDD.csv to ACME SFTP /inbound/reports linux-app01
svc-xfer-acme (key)
Infrastructure — J. Rivera Active, verified Mar 14
payroll-export-upload
Task Scheduler, Fri 18:30
Weekly payroll file to bank SFTP drop win-fin02
CORP\svc-payroll (key)
Finance IT — duty rota Active, verified Feb 02
partner-orders-watch
folder monitor (event)
Inbound order files to ERP import share win-mft01
CORP\svc-mft (key)
Operations — T. Chen Active, verified Mar 02
SyncJob2-new
Task Scheduler, 03:00 daily
Unknown CSVs to plain-FTP host that no longer resolves win-old04
local Administrator (password)
Unknown Suspect — investigating

Row four is what a healthy inventory looks like mid-cleanup: the ghost is named, visible, and assigned a status, instead of running in the dark. Suspect rows are not embarrassments — they are the inventory doing its job.

Spotting the Dead and the Undead

With everything listed, the triage begins. Forgotten jobs come in two varieties, and they need different tests.

Dead jobs have already stopped working — they fail every run, or never fire at all — and nobody noticed, which tells you something important: their output was not missed. The evidence is usually one query away. The scheduler's own records show it: cron failures accumulate in the system mail spool or syslog, and the schtasks /query /v export includes each task's last run time and last result, so sorting that CSV by result code surfaces every serially failing task on the host at once. A log file that stopped growing months ago is the same signal — and if you can read the destination server's logs, an account that stopped logging in tells the story from the other end (reading transfer logs covers the technique). Dead jobs are the easy wins: confirm with the owner if one exists, then retire them through the ritual below — including revoking their credentials, which very much did not die with them.

Undead jobs are the subtler problem: they run successfully, every night, to no purpose. The transfer completes; the file lands; nobody reads it. Success metrics will never flag them, so the test is consumption, not execution. Ask the receiving side what they do with the file — the question "what would break if this stopped arriving Monday?" gets remarkably honest answers. Check whether anything downstream processes the delivered files or whether they simply accumulate (a destination folder holding hundreds of unprocessed files, neatly datestamped, is a monument to an undead job). Where the destination is a partner, ask the partner; businesses change their processes without telling the counterpart's IT department, in both directions.

Remember: a job that runs green every night can still be pure waste, and a job that fails every night can still be load-bearing (its consumers may be limping along on a manual workaround, wondering why the feed broke). Execution status and business value are separate questions. The inventory exists to hold both.

Retiring a Job Without Breaking the Business

Retirement is where hidden dependencies bite, so it is done as a ritual with waiting periods, not a deletion. The steps, in order:

  1. Announce. Tell the likely interested parties — owner, downstream team, partner contact — that the job is believed obsolete and will be suspended on a named day. Sometimes this step alone resurrects an owner.
  2. Disable, do not delete. Turn the job off in its scheduler but leave the job, its script, and its configuration untouched. A disabled job can be re-enabled in one minute; a deleted one is an afternoon of reconstruction — if the script still exists anywhere.
  3. Watch through a full business cycle. Not a week — a cycle. Month-end, quarter-end, and that one report someone runs occasionally are where hidden dependencies live. Keep a note in the inventory row: "suspended, watching until end of quarter."
  4. Listen for screams. A complaint is a success: the dependency surfaced safely, with the job one click from restored. Re-enable, record the newly discovered consumer and owner in the inventory, and be glad the discovery cost an apology instead of an incident.
  5. Then dismantle deliberately. After a silent cycle: archive the script and configuration somewhere findable, remove the job, and — the step most often skipped — revoke its credentials everywhere: disable the account, remove the key from the partner's server, and ask the partner to confirm. A retired job whose key still opens a partner system is not retired; it is an unattended door.
  6. Close the record. Mark the inventory row retired, with when and why. Tomorrow's administrator, finding a reference to the job in an old document, deserves a one-line answer instead of a mystery.

If you inherit rather than retire — the job turns out to be alive and important, but undocumented — the salvage procedure is different, and inheriting FTP automation you did not build walks through it: understand before touching, document as you learn, then bring the job up to the standards of this series one rung at a time.

Keeping the Inventory Alive

A one-time sweep produces a snapshot; the value is in keeping it true. Three habits do it, none expensive.

The birth rule. No job gets a schedule or a trigger without an inventory row — same commit, same afternoon. This was the closing advice of from script to schedule, and it is the single highest-leverage habit in this article: debt is overwhelmingly cheaper to prevent than to excavate. Make the row part of the definition of done, the way the script header is.

The periodic walk. Twice a year, walk the inventory: does each job still run, is each output still consumed, does each owner still exist, which credentials expire before the next walk? Twenty rows take an hour. The walk also re-runs a light version of the hunt — one schtasks export per Windows host, one crontab sweep per Unix host, compared against the inventory — to catch jobs born outside the birth rule. Fewer places to look makes this dramatically easier, which is a real argument for consolidation: transfer tasks gathered into one tool's scheduler — on Windows, for instance, the task list in Sysax FTP Automation, with its schedules and email notifications attached — are tasks the walk can review in one screen instead of eleven servers.

The offboarding hook. When someone leaves or changes teams, the inventory answers "which jobs did they own, and which run as accounts tied to them?" — in minutes, while the knowledge is still in the building. This is also the moment ownership transfers get recorded, instead of discovered by absence two years later.

One more return on the investment: the inventory is audit gold. When a security review or a compliance audit asks "what automated processes move data out of your network, who owns them, and how are they credentialed?" — a question that appears, in some phrasing, in nearly every framework — the inventory is the answer, current and defensible. The connection between everyday operational records and audit readiness is a theme of our audit-ready reporting series; this is one of its clearest examples.

From Haunted House to Estate

The automation ladder, climbed flow by flow, leaves you with dozens of jobs running unattended — that was the goal, and it is worth having. The inventory is what keeps that collection an estate rather than a haunted house: every job findable, owned, explicable, and mortal — able to be retired on purpose when its purpose ends. The disciplines are small: a row at birth, a walk twice a year, a ritual at death. The alternative is the decommissioning-day scene this article opened with, plus interest.

If you are starting from zero, start narrow: hunt one server this week, inventory what you find, retire one obvious ghost through the full ritual. The habits scale up from there. And as new flows climb the ladder — through first scripts, schedules, and event-driven designs — each one enters the world already recorded, which is how the next decade of automation avoids becoming the next decade's debt.

Frequently Asked Questions

Do we really need an inventory if we only have a handful of jobs?
A handful is the perfect time to start — ten rows take an hour, and the birth-rule habit forms while the estate is still small. Every large, unmapped estate was once a handful that someone decided was too small to bother writing down.
What tool should the inventory live in?
Whatever your team already reads: a spreadsheet or a wiki page beats a specialized system nobody opens. The requirements are only that it is shared, editable, findable by a stranger, and reviewed on a schedule. Boring technology is a feature here.
How do I find jobs that are not in cron or Task Scheduler?
Check the schedulers inside transfer tools and business applications, systemd timers, services wrapping scripts, and appliances like NAS boxes — then hunt from the other end by reading your transfer servers' logs for accounts that connect on a rhythm. Every regular nocturnal login belongs to some job; find its home.
Is it safe to just delete a job that has been failing for months?
Follow the ritual anyway: announce, disable, and watch a business cycle before dismantling. Serial failure usually means unneeded, but occasionally the consumers are surviving on a painful manual workaround and the fix, not the funeral, is what is wanted. Either way, revoke the job's credentials at the end — those never die on their own.
Who should own the inventory itself?
One named role — typically whoever owns transfer infrastructure — owns the document, the review calendar, and the birth rule. Individual rows keep their own owners. Shared ownership of the whole file means no ownership; the inventory needs exactly the thing it records.

From the Sysax team: we build secure file transfer software for Windows — Sysax Multi Server, an FTP, FTPS, SFTP, and HTTPS server, and Sysax FTP Automation for scheduled, scripted transfers. Free trials are on the download page.