Schedule a weekly AI summary with Windows Task Scheduler (with a human OK step)

How I queue a weekly AI summary with Windows Task Scheduler (and why a human still presses OK)

My AI assistant had one big weakness: it does nothing until I open it. Every Sunday night I was supposed to ask it to summarize my week, and I forgot more often than I remembered. Windows Task Scheduler fixed the forgetting part. At 10 pm every Sunday, Windows runs a small PowerShell script that drops a signal file and notifies me. The AI does not run at 10 pm. The next time I open a session, the AI sees the signal file and tells me a weekly job is waiting. I press OK, and only then does it do the work. During my 14-day trial, my first approach failed and I ran into two bugs in the first week. I also added three guardrails.

I call the whole setup "Jarvis." Everyone names their assistant, and I'm no exception.

Attempt 1: telling the AI "run at 10 pm on Sundays" (failed)

My first idea was to write the schedule into the AI's own instructions: "Every Sunday at 22:00, do the weekly summary."

It worked only if I happened to open the AI at 10 pm on a Sunday. If I didn't, nothing happened. When I opened it on the next Tuesday, it asked, "Should I process last Sunday's job?"

I still had to remember to open the AI myself, which was the step I'd wanted to automate.

What worked: queue the job from the OS

The answer was already in Windows. Task Scheduler is built in, and it can run a PowerShell script at a set time. Instead of putting the schedule inside the AI, I moved it to the operating system. Windows leaves a signal file for the AI to read when I next open it.

The flow:

  1. Sunday 22:00: Windows runs a PowerShell script.
  2. The script creates a signal file and sends me a notification.
  3. Later, I open an AI session myself. At session start it reads the signal folder and says a weekly job is waiting.
  4. I press OK. Only then does it run the job and write up the results.

I put Windows in charge of the schedule and left the work to the AI session. It doesn't matter how I open the AI (desktop app, CLI, or an extension inside an IDE). If the signal file is there, the session picks it up.

Why a human still presses OK

I kept step 4 on purpose. The scheduled part only creates a to-do. Anything the AI actually does happens in a session I opened, after I approved it. If the signal shows up at a bad time, I can leave it waiting. Nothing runs behind my back at 10 pm.

Week 1, bug 1: the PC was off

After setup, the first Sunday came and went with no alert. My PC was off at 10 pm. (Yes, I'd forgotten that Task Scheduler needs the PC to be on.)

The fix was one setting: StartWhenAvailable ("Run task as soon as possible after a scheduled start is missed" in the task's Settings tab). With it on, Task Scheduler can start a missed run after the PC is back on. Microsoft's documentation says it starts after a delay, so it's not instant, and I wouldn't treat it as a guarantee: TaskSettings.StartWhenAvailable. In my case, after I turned it on, the signal arrived shortly after booting, even when the laptop had been off for days.

Week 1, bug 2: it fired twice

The second bug: if I turned the PC on twice in one week, the task could fire twice. My fix was to mark the signal file with the week, so a second run in the same week stops early. In my own setup that mark was the ISO week number.

A minimal version of the setup

Here is a minimal sketch of the two pieces, written for Windows PowerShell 5.1 (the version built into Windows). It is not my exact script. Paths are placeholders. I registered mine once from an administrator PowerShell window.

One change from my original: the sketch keys each signal on the scheduled occurrence it belongs to (a specific Sunday at 22:00), not the day the script happens to run. It takes this week's Sunday 22:00, and if that moment hasn't arrived yet, it steps back 7 days. So a catch-up run on Tuesday, or even on Sunday morning, still counts as the previous Sunday's run, and the real 22:00 run on Sunday gets its own key. It also leaves a small marker file per occurrence that stays behind after the signal itself has been processed, so the same occurrence can't be queued twice.

Registering the weekly task:

$script   = "C:\path\to\weekly_signal.ps1"
$action   = New-ScheduledTaskAction -Execute "powershell.exe" `
            -Argument "-NoProfile -ExecutionPolicy Bypass -File `"$script`""
$trigger  = New-ScheduledTaskTrigger -Weekly -DaysOfWeek Sunday -At 10pm
$settings = New-ScheduledTaskSettingsSet -StartWhenAvailable `
            -ExecutionTimeLimit (New-TimeSpan -Minutes 5)

Register-ScheduledTask -TaskName "WeeklySummarySignal" `
    -Action $action -Trigger $trigger -Settings $settings

The signal script (Windows PowerShell 5.1 compatible):

# weekly_signal.ps1 (sketch)
$ErrorActionPreference = "Stop"
$kill      = "C:\path\to\_KILL_SWITCH"
$signalDir = "C:\path\to\signals"

# Error log lives outside the signal folder, so logging works even if that folder is missing
$logDir  = Join-Path $env:LOCALAPPDATA "WeeklySignal"
$logFile = Join-Path $logDir "weekly_signal.log"
New-Item -ItemType Directory -Path $logDir -Force | Out-Null

try {
    # Kill switch: checked once, when the script starts
    if (Test-Path $kill) { exit 0 }

    # Key = the most recent scheduled occurrence (Sunday 22:00), date and time together
    $now        = Get-Date
    $thisSunday = $now.Date.AddDays(-[int]$now.DayOfWeek)   # Sunday = 0
    $occurrence = $thisSunday.AddHours(22)                   # this week's Sunday at 22:00
    if ($occurrence -gt $now) { $occurrence = $occurrence.AddDays(-7) }   # not reached yet -> last week's
    $key = $occurrence.ToString("yyyy-MM-dd_HHmm")

    New-Item -ItemType Directory -Path $signalDir -Force | Out-Null
    $signal = Join-Path $signalDir "weekly_summary_$key.txt"     # the to-do; the AI session removes it when done
    $marker = Join-Path $signalDir "weekly_summary_$key.queued"  # stays behind after the signal is processed
    if (Test-Path $marker) { exit 0 }                            # this occurrence was already queued once

    Set-Content -Path $signal -Value "pending"
    Set-Content -Path $marker -Value "queued $($now.ToString('s'))"
    # (notification step omitted)
}
catch {
    Add-Content -Path $logFile -Value "$(Get-Date -Format s) ERROR $($_.Exception.Message)"
    exit 1
}

This sketch creates 1 signal file and 1 marker file per scheduled occurrence. The session deletes the signal file once the job is done; the marker stays, which is what blocks a second queue for the same occurrence. Then, in the instructions the AI reads at the start of each session, I added one rule: check the signals folder, and if a pending file exists, tell me and wait for my OK.

The test on my real setup

Right after registering my real task, I ran it once by hand to verify. Results:

  • Task status: success (LastResult 0)
  • 2 signal files created (my setup queues that week's batch of scheduled jobs, so it writes more than the 1 file in the sketch)
  • Next automatic run: the following Sunday at 22:00 sharp

The weekly "I need to remember to ask for that" feeling went away. I still open the AI and press OK, but I no longer have to remember that the job exists.

3 guardrails: stopping well matters as much as starting

I added these at the same time, and all 3 are in the sketch above:

  1. Once per scheduled occurrence. The same job can't queue twice for the same Sunday 22:00, because the marker file for that occurrence stays even after the signal is processed.
  2. 5-minute limit. If the task hasn't finished in 5 minutes, Task Scheduler stops it.
  3. Kill switch at start. If a small marker file exists when the script starts, it exits without doing anything. It does not stop a run that is already in progress.

I'd seen an automation get stuck in an infinite loop before, so this time I added the safeguards first.

The same tool, 2nd job: a daily balance check at 4 a.m.

I used Task Scheduler for a second chore. I used to open my brokerage app several times a day (before work, at lunch, after work) just to see balances. That ate about 30 minutes a day.

I registered a Python script to run every day at 4 a.m. It pulls the balances of 2 accounts, a tax-advantaged savings account and a retirement account, adds them up, compares them to the previous day, and updates a dashboard. When I wrote my log, it had refreshed itself 14 days in a row.

It also failed once. During setup I handled the API token refresh wrong, and for 3 days no data came in. When I looked again, the market had moved and some holdings were down 5% and 7%. I had trusted the automation, stopped looking, and missed my chance to act.

The balances now update automatically. I still make the buy and sell decisions and check the big picture myself once a week.

How I use it now:

  • Every day, early morning: balances refresh and the dashboard updates on their own.
  • Sunday night, weekly: I write a short note on the week's trades and why I made them.
  • Monthly, once: I check progress against my dividend goal.

If you want to copy this

I'm not a developer, and this setup took three things:

  1. One PowerShell script. There are many similar examples online, and if you ask an AI assistant to write it, it takes about 30 minutes.
  2. One Task Scheduler registration. Run it once from an administrator PowerShell window, and turn on StartWhenAvailable.
  3. Signal-file detection. Add a line to the instructions your AI reads at session start: check for pending signal files, then ask before running anything.

Then do 2 tests before you trust it. Run the task by hand once and confirm LastResult 0. Then leave the PC off over a scheduled time, boot it, and check whether the missed run starts and how long it takes on your machine.

Comments

Popular posts from this blog

Python script works manually but not in Task Scheduler: the Microsoft Store python stub (and a daily alive check)

Codex vs Claude Code: which jobs I give each (3 months of work logs)

What not to automate with AI: my approval rule for money and irreversible actions

Telegram bot receives /start automatically: how it triggered my kill switch (one-line fix)