What it does
The Ops Schedules page (under the Tasking nav group) lets you run library scripts on a recurrence - hourly, daily, weekly, or monthly. Each run is captured with full per-target output, and consecutive runs are compared for drift. When drift or failure is detected, configurable action rules fire email notifications or open Tasker tasks for follow-up.
Use cases
- Configuration drift detection - Run a "report current state" script daily; get alerted when output changes (registry key flipped, service stopped, group membership changed).
- Compliance evidence collection - Capture proof of control state on a recurring basis. Each run is a timestamped snapshot in OpsScheduleRuns with full stdout/stderr.
- Remediation drift watch - After remediating a finding, schedule a daily verification script. Get a Tasker task opened the moment the remediation reverts.
- Tenant-wide M365 enforcement - Cloud-target scripts (โ๏ธ) run against Graph/EXO from a runbook context, not on endpoints. Example: ensure mailbox Calendar default permission stays Reviewer (Caron Bletzer's first use case).
Script execution-target taxonomy ADO #498
Every library script is tagged with an executionTarget field that determines where and how it runs:
| Target | Icon | Where it runs | Requires targets? |
|---|---|---|---|
device | ๐ฅ๏ธ | Dispatched to Windows hostnames via the TATER Agent's command-poll loop | Yes - one or more lowercase hostnames |
cloud | โ๏ธ | Runs against an M365/Entra tenant via Graph or EXO from a runbook or interactive admin session | No - leave targets empty |
hybrid | ๐ | Author opt-in for both modes (rare) | Yes when used in device mode |
Why this matters: a cloud script attempted via the device-execute path will fail at runtime - there's no agent to receive it. The scheduler enforces the contract at save time: cloud scripts cannot have device targets, device/hybrid scripts must have at least one. Existing scripts default to device (matches prior behavior).
Cloud auth context (optional companion)
Cloud scripts can additionally declare cloudAuthContext to document what auth the runbook host must provide. Values:
exo-managed-identity- Exchange Online cmdlets via Automation Account managed identitygraph-managed-identity- Microsoft Graph via Automation Account managed identityexo-interactive- Exchange Online cmdlets via interactive admin sign-ingraph-interactive- Microsoft Graph via interactive admin sign-inazure-managed-identity- Azure Management API via managed identity
Creating a schedule
- Open TATER Ops โ Tasking โ Schedules and click + New Schedule.
- Pick a script. The dropdown shows the execution-target icon next to each script.
- For device/hybrid scripts: enter target hostnames (one per line, lowercase). Cloud scripts leave this empty.
- Set the recurrence - frequency, UTC time, and (where applicable) day of week / day of month.
- Add action rules. Trigger options: on-drift, on-failure, or always. Action options: email (with recipients) or tasker-task (with category + priority).
- Save. The cron checks every 5 minutes and runs schedules whose
nextRunAthas passed.
How drift detection works
When a run completes, the scheduler queries the most recent previous run for the same schedule and compares normalized stdout per target. Any host whose stdout differs from the prior run is flagged. The run record stores:
driftDetected: true/falsedriftSummary.changedTargets- list of hostnames that changeddriftSummary.sampleDiff- first ~2KB of difference (truncated)
When drift is found, run status rolls up to Drift (instead of Success) so it shows up amber in the runs list and triggers any on-drift action rules.
Drift detection precision
Phase 1 compares whitespace-normalized stdout text. Scripts that emit timestamps, GUIDs, or other always-changing data will appear to drift every run. Best practice: structure your script output so the stable signal (config values, group membership IDs, permission strings) is on its own lines, separated from the noisy metadata. Phase 2 will add JSON diff with per-property Before/After.
Action rules
Each schedule supports up to 20 action rules. They fire after a run finalizes, in order of trigger:
- on-drift - fires when
driftDetected = true. Use to flag configuration changes for review. - on-failure - fires when run status is
FailedorMixed. Use to escalate broken automation. - always - fires on every completed run. Use for low-volume nightly status emails.
Email actions send via the configured notifications channel (Graph or SMTP). Tasker-task actions create a new task in TATER Ops under the supplied category and priority, with the run summary embedded in the task description and the originating schedule linked.
Recent runs & per-target output
The Recent Runs tab lists the last 50 runs across all schedules. Click any row to open the run detail modal, which shows:
- Drift diff panel (amber) - sample of what changed between consecutive runs
- Per-target table - host, status, exit code, duration, and clipped stdout (2KB per host)
- For Skipped runs (cloud scripts in Phase 1) - the reason the run was skipped
Cloud script execution status ADO #497 Phase 1
Phase 1 ships the schema, scheduler, drift engine, and action rules end-to-end. Cloud scripts are scheduled and tracked but their actual execution path is Phase 2: today the scheduler records a Skipped run with the diagnostic "Cloud-execution channel not yet wired (Phase 2)" and advances nextRunAt so cron doesn't hot-loop. Phase 2 will wire Azure Automation runbook trigger + interactive admin handoff using cloudAuthContext to route. Device scripts run normally end-to-end today.
Permissions
- Auditor+ - view schedules, view runs.
- Admin+ - create, edit, delete schedules; trigger ad-hoc runs.
Related
- Ops customization - categories, priorities, statuses, teams.
- Agent deployment - getting the TATER Agent installed on target devices.
- MCP setup - using AI agents to query schedule history and trigger runs.