<# .SYNOPSIS Register (or remove) the two Windows scheduled tasks that make AVWatch run by itself. .DESCRIPTION Creates: "AVWatch Scan" mid-week checks. Cheap: it only asks Claude about versions it has never seen before, and reuses cached web lookups. Writes reports\latest.html. No email. "AVWatch Digest" the Monday briefing. Full pass, every outstanding update gets a verdict, then the email goes out. Tasks run as the current user so they inherit your environment variables (API key, SMTP password). They are set to run whether or not you are logged in, and to start late if the machine was off at the scheduled time. Run this from a normal PowerShell window -- no administrator rights are needed for a per-user task. .EXAMPLE .\install_tasks.ps1 .\install_tasks.ps1 -ScanDays Tuesday,Thursday,Saturday -ScanTime 06:00 -DigestTime 07:15 .\install_tasks.ps1 -Remove #> [CmdletBinding()] param( [string[]]$ScanDays = @('Tuesday', 'Thursday', 'Saturday'), [string]$ScanTime = '06:00', [string]$DigestDay = 'Monday', [string]$DigestTime = '07:00', [string]$ProjectRoot, [switch]$Remove ) $ErrorActionPreference = 'Stop' if (-not $ProjectRoot) { $ProjectRoot = Split-Path -Parent $PSScriptRoot } $runner = Join-Path $ProjectRoot 'scripts\run_avwatch.ps1' $scanTaskName = 'AVWatch Scan' $digestTaskName = 'AVWatch Digest' if ($Remove) { foreach ($name in $scanTaskName, $digestTaskName) { if (Get-ScheduledTask -TaskName $name -ErrorAction SilentlyContinue) { Unregister-ScheduledTask -TaskName $name -Confirm:$false Write-Output "removed scheduled task: $name" } else { Write-Output "not present: $name" } } return } if (-not (Test-Path $runner)) { throw "runner script not found: $runner" } # --- sanity check before we schedule anything --------------------------- Write-Output "Checking the setup first..." Push-Location $ProjectRoot try { $venvPython = Join-Path $ProjectRoot '.venv\Scripts\python.exe' if (Test-Path $venvPython) { $python = $venvPython } else { $python = (Get-Command python).Source } & $python -m avwatch doctor if ($LASTEXITCODE -ne 0) { Write-Warning ("'avwatch doctor' reported problems (exit $LASTEXITCODE). " + "Scheduling anyway -- fix them and the tasks will start working.") } } finally { Pop-Location } $principal = New-ScheduledTaskPrincipal -UserId "$env:USERDOMAIN\$env:USERNAME" ` -LogonType S4U -RunLevel Limited $settings = New-ScheduledTaskSettingsSet ` -StartWhenAvailable ` -DontStopOnIdleEnd ` -AllowStartIfOnBatteries ` -DontStopIfGoingOnBatteries ` -MultipleInstances IgnoreNew ` -ExecutionTimeLimit (New-TimeSpan -Hours 3) function New-AvwatchAction([string]$Command) { # -NoProfile keeps a slow or broken PowerShell profile out of the picture. $argument = ('-NoProfile -NonInteractive -ExecutionPolicy Bypass -File "{0}" ' + '-Command {1} -ProjectRoot "{2}"') -f $runner, $Command, $ProjectRoot New-ScheduledTaskAction -Execute 'powershell.exe' -Argument $argument ` -WorkingDirectory $ProjectRoot } # --- mid-week scans ------------------------------------------------------ $scanTrigger = New-ScheduledTaskTrigger -Weekly -DaysOfWeek $ScanDays -At $ScanTime Register-ScheduledTask -TaskName $scanTaskName ` -Action (New-AvwatchAction 'scan') ` -Trigger $scanTrigger ` -Principal $principal ` -Settings $settings ` -Description ("AVWatch: check the AV fleet for new firmware and software " + "releases and refresh reports\latest.html. No email.") ` -Force | Out-Null Write-Output "registered: $scanTaskName ($($ScanDays -join ', ') at $ScanTime)" # --- Monday digest ------------------------------------------------------- $digestTrigger = New-ScheduledTaskTrigger -Weekly -DaysOfWeek $DigestDay -At $DigestTime Register-ScheduledTask -TaskName $digestTaskName ` -Action (New-AvwatchAction 'digest') ` -Trigger $digestTrigger ` -Principal $principal ` -Settings $settings ` -Description ("AVWatch: full update-and-risk pass, then email the weekly " + "briefing to the recipients in config.toml.") ` -Force | Out-Null Write-Output "registered: $digestTaskName ($DigestDay at $DigestTime)" Write-Output "" Write-Output "Done. Useful commands:" Write-Output " Start-ScheduledTask -TaskName '$digestTaskName' # run the digest now" Write-Output " Get-ScheduledTaskInfo -TaskName '$digestTaskName' # last run time and result" Write-Output " Get-ChildItem '$ProjectRoot\logs' | Sort LastWriteTime -Desc | Select -First 5" Write-Output "" Write-Output "Secrets must be set as USER environment variables so the tasks" Write-Output "inherit them. For example:" Write-Output ' setx ANTHROPIC_API_KEY "sk-ant-..."' Write-Output ' setx AVWATCH_SMTP_PASSWORD "your-app-password"' Write-Output "Open a new shell after setx before testing."