Scheduled jobs fail the way trees fall in empty forests: the backup-rotation script has been erroring since March and nobody knew, because nobody knew it existed. Every scheduled automation gets two artifacts — a runbook page and a smoke test — and AI writes 80% of both from the script itself.
Tier: Foundation · Workflow area: Scripting & automation · ~25 minutes per automation
This playbook inventories every scheduled task, cron job and RMM automation in your estate, then generates for each a one-page runbook (what it does, when, as whom, what depends on it) and a smoke test that proves it actually ran — turning silent failures into loud ones.
Inventory everything that runs on a schedule. Windows tasks, cron, and the RMM's automation list:
Get-ScheduledTask | Where-Object State -ne Disabled |
Select-Object TaskName, TaskPath,
@{n="RunAs";e={$_.Principal.UserId}},
@{n="LastResult";e={($_ | Get-ScheduledTaskInfo).LastTaskResult}},
@{n="LastRun";e={($_ | Get-ScheduledTaskInfo).LastRunTime}} |
Export-Csv .\task-inventory.csv -NoTypeInformation
for u in $(cut -f1 -d: /etc/passwd); do crontab -l -u "$u" 2>/dev/null \
| sed "s/^/$u: /"; done; ls /etc/cron.d /etc/cron.daily
Non-zero LastTaskResult values in that first export are your instant hit list — silent failures already in progress.
Generate the runbook page per automation. Feed each script (or RMM automation config) to the model:
Write a one-page runbook for this scheduled automation.
Sections:
- Purpose: what it does and WHY it exists (mark WHY as
[OWNER TO CONFIRM] if not evident from the script)
- Schedule & identity: when it runs, as what account, from where
- Inputs/outputs: files, APIs, databases, emails touched
- Dependencies: what breaks if this stops; what this breaks if wrong
- Failure signature: what a failed run looks like (exit codes,
missing output, log lines) — from the script's actual error paths
- Manual run procedure: exact command to run it by hand safely
- Owner and review-by date: [FILL]
Script: [paste] Schedule/context: [paste from inventory]
Fill the human-only fields. The model reads code; it cannot know that the CSV this job drops is what payroll imports on the 25th. The owner confirms the WHY, the downstream dependents and the business impact — ten minutes per job, and the only part that requires a human.
Generate the smoke test — proof of effect, not proof of schedule. The test checks the job's output, not its exit code:
Write a PowerShell smoke test for this automation. It must verify
EFFECTS, not just that the task ran:
- the expected output artifact exists and is fresher than [interval]
- the artifact is non-trivial (size/row-count above a floor)
- key content sanity check: [e.g., header row matches, no ERROR lines]
On any failure: write an event-log entry and send one alert to
[channel/email]. On success: silent.
Automation runbook: [paste the page from step 2]
Sample of the core assertion pattern:
$f = Get-Item "\\fs01\reports\daily-export.csv" -ErrorAction SilentlyContinue
if (-not $f -or $f.LastWriteTime -lt (Get-Date).AddHours(-26)) {
Write-EventLog -LogName Application -Source "SmokeTest" -EntryType Error `
-EventId 9001 -Message "daily-export.csv missing or stale"
Send-Alert "SMOKE FAIL: daily-export stale ($($f.LastWriteTime))"
} elseif ((Import-Csv $f.FullName).Count -lt 50) {
Send-Alert "SMOKE FAIL: daily-export suspiciously small ($($f.Length) bytes)"
}
The staleness window (26h for a daily job) and the row-count floor are the two numbers that catch the "ran but produced nothing" class.
Schedule the smoke tests offset from their targets. Each test runs after its automation's window (job at 02:00, test at 04:00) and alerts to a channel someone reads. Review the smoke tests with the pb-21 checklist — they are scripts too.
Break something on purpose. For each smoke test, force one failure in a controlled way (rename the output file, point the job at a dead path in a test window) and confirm the alert fires and reaches a human. An untested smoke test is a second silent failure waiting behind the first.
Keep the register. One table: automation | host | owner | runbook link | smoke test | last verified. New automations don't ship without a row; the register is what you hand the auditor, the new starter (pb-20), and your successor.
Task inventories reveal service-account names and infrastructure layout, and scripts often embed paths and credentials — sanitize before external assistants, and treat the register itself as internal-confidential.
A scheduled automation without a runbook and an effect-checking smoke test is a silent failure on a timer — AI makes both artifacts cheap enough that "we didn't have time to document it" stops being true.