Files
AV-Watch/scripts/install_tasks.ps1
T

132 lines
5.0 KiB
PowerShell

<#
.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."