- Panoramica
- Notazione delle variabili
- Step 1: Registrazione del task e impostazioni di base
- Step 2: Trigger su registro eventi (con template XML)
- Step 3: Combinare trigger e condizioni di esecuzione
- Step 4: Gestione dei task esistenti
- Abilitare il registro operativo (Operational Log)
- Step 5: Troubleshooting e verifica log
- Step 6: Raccomandazioni
- Conclusione
Panoramica
Questo articolo spiega come usare Windows Task Scheduler per costruire un’automazione avanzata:
copre i trigger condizionali, l’esecuzione collegata al registro eventi, la registrazione e il controllo dei task con PowerShell, e le buone pratiche di sicurezza operative.
Notazione delle variabili
| Variabile | Esempio | Nota |
|---|---|---|
<<TASK_NAME>> |
Daily-Backup |
Nome del task |
<<SCRIPT_PATH>> |
C:\Scripts\backup.ps1 |
Percorso dello script da eseguire |
<<EVENT_ID>> |
4625 |
Event ID che attiva il trigger |
<<USERNAME>> |
Administrator |
Utente che esegue il task |
<<TASK_PATH>> |
\MyCompany\Maintenance |
Cartella nella Libreria attività (opzionale) |
Step 1: Registrazione del task e impostazioni di base
Per registrare un task con PowerShell si combinano tre cmdlet principali:
| Cmdlet | Ruolo |
|---|---|
New-ScheduledTaskAction |
Definisce il programma/lo script da eseguire |
New-ScheduledTaskTrigger |
Definisce il momento di esecuzione (tempo/eventi) |
Register-ScheduledTask |
Registra il task completo (Action + Trigger + Settings) |
① Opzioni principali di New-ScheduledTaskAction
| Opzione | Descrizione | Esempio |
|---|---|---|
-Execute |
Eseguibile | "powershell.exe" |
-Argument |
Argomenti CLI | "-NoProfile -NonInteractive -ExecutionPolicy Bypass -File <<SCRIPT_PATH>>" |
-WorkingDirectory |
Directory di lavoro | "C:\Scripts" |
-Id |
Identificatore per più azioni | "Action1" |
💡 Per più azioni, creare più oggetti
New-ScheduledTaskActione passarli come array.
② Opzioni principali di New-ScheduledTaskTrigger
| Opzione | Descrizione | Esempio |
|---|---|---|
-Daily |
Esecuzione giornaliera | Usare con -At 3:00AM |
-Weekly |
Esecuzione settimanale | -DaysOfWeek Monday,Wednesday |
-Once |
Esecuzione singola | -At (Get-Date).AddHours(1) |
-AtStartup |
All’avvio del sistema | — |
-AtLogOn |
Al logon utente | — |
-RepetitionInterval |
Intervallo ripetizione | (New-TimeSpan -Minutes 30) |
-RepetitionDuration |
Durata ripetizione | (New-TimeSpan -Days 1) |
-RandomDelay |
Ritardo casuale | (New-TimeSpan -Minutes 5) |
-StartBoundary / -EndBoundary |
Finestra di validità | "2025-01-01T00:00:00" |
⚠️
-RepetitionIntervale-RepetitionDurationsono validi solo per alcuni tipi di trigger (es. Daily/Once).
③ Opzioni principali di New-ScheduledTaskSettingsSet (facoltativo)
| Opzione | Descrizione | Esempio |
|---|---|---|
-AllowStartIfOnBatteries |
Consenti avvio a batteria | $false |
-DontStopIfGoingOnBatteries |
Non interrompere se passa a batteria | $false |
-StartWhenAvailable |
Avvia appena possibile | $true |
-Hidden |
Nascondi il task | $true |
-RunOnlyIfNetworkAvailable |
Richiedi rete disponibile | $true |
-ExecutionTimeLimit |
Timeout massimo | (New-TimeSpan -Hours 2) |
-MultipleInstances |
Politica multi-istanza (IgnoreNew/Parallel/Queue) | "IgnoreNew" |
-RestartCount / -RestartInterval |
Tentativi e intervallo di riavvio | 3, (New-TimeSpan -Minutes 5) |
💡
New-ScheduledTaskSettingsSetgenera l’oggetto passato a-Settingsper gestire in modo centralizzato alimentazione, rete e retry.
④ Opzioni chiave di Register-ScheduledTask
| Opzione | Descrizione | Esempio |
|---|---|---|
-TaskName |
Nome del task | "Daily-Backup" |
-TaskPath |
Cartella nella Libreria | "\MyCompany\Maintenance" |
-Action |
Oggetto azione | $action |
-Trigger |
Oggetto trigger | $trigger |
-Settings |
Impostazioni aggiuntive | $settings |
-Description |
Descrizione | "Daily maintenance backup task" |
-User |
Account di esecuzione | "SYSTEM" o "Administrator" |
-RunLevel |
Livello privilegi | Highest |
-Force |
Sovrascrive se esiste | — |
💡 Un task completo = combinazione di
Action+Trigger+Settings.
⑤ Esempio di configurazione
# Definisci l'azione
$action = New-ScheduledTaskAction -Execute "powershell.exe" `
-Argument "-NoProfile -ExecutionPolicy Bypass -File <<SCRIPT_PATH>>"
# Definisci il trigger (tutti i giorni alle 03:00)
$trigger = New-ScheduledTaskTrigger -Daily -At 3:00AM
# Registra il task
Register-ScheduledTask -TaskName "<<TASK_NAME>>" `
-TaskPath "<<TASK_PATH>>\Daily" `
-Action $action -Trigger $trigger `
-User "<<USERNAME>>" -Description "Task pianificato alle 03:00 ogni giorno"
⑥ Note operative
-ExecutionPolicy Bypasssolo in ambienti interni e controllati; in produzione preferire script firmati.- Account di esecuzione: SYSTEM o account di servizio dedicato (principio del minimo privilegio).
-RepetitionIntervalminimo 1 min;-RepetitionDurationspesso con limite di default 1 giorno.- Per sovrascrivere, specificare esplicitamente
-Force. -RunLevel Highestsolo se servono privilegi amministrativi.
Step 2: Trigger su registro eventi (con template XML)
New-ScheduledTaskTrigger oggi non espone direttamente il trigger su evento (es. -OnEvent).
Per usare un trigger su eventi, importare una definizione XML.
Registrazione:
$xml = @'
<Task version="1.3" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
<RegistrationInfo>
<Author><<USERNAME>></Author>
<Description>Esegui lo script quando si verifica l'Event ID <<EVENT_ID>></Description>
</RegistrationInfo>
<Triggers>
<EventTrigger>
<Enabled>true</Enabled>
<Subscription><![CDATA[
<QueryList>
<Query Id="0" Path="Security">
<Select Path="Security">*[System[(EventID=<<EVENT_ID>>)]]</Select>
</Query>
</QueryList>
]]></Subscription>
</EventTrigger>
</Triggers>
<Principals>
<Principal id="Author">
<UserId>SYSTEM</UserId>
<RunLevel>HighestAvailable</RunLevel>
</Principal>
</Principals>
<Settings>
<MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy>
<DisallowStartIfOnBatteries>false</DisallowStartIfOnBatteries>
<StopIfGoingOnBatteries>true</StopIfGoingOnBatteries>
<AllowHardTerminate>true</AllowHardTerminate>
<StartWhenAvailable>true</StartWhenAvailable>
<ExecutionTimeLimit>PT1H</ExecutionTimeLimit>
<Priority>7</Priority>
</Settings>
<Actions Context="Author">
<Exec>
<Command>C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe</Command>
<Arguments>-NoProfile -ExecutionPolicy Bypass -File "<<SCRIPT_PATH>>"</Arguments>
</Exec>
</Actions>
</Task>
'@
Register-ScheduledTask -TaskName "<<TASK_NAME>>" -TaskPath "<<TASK_PATH>>\OnEvent" -Xml $xml -User "SYSTEM"
Step 3: Combinare trigger e condizioni di esecuzione
Definire le “Condizioni” (alimentazione, rete, idle) con New-ScheduledTaskSettingsSet.
$settings = New-ScheduledTaskSettingsSet `
-AllowStartIfOnBatteries:$false `
-DontStopIfGoingOnBatteries:$false `
-StartWhenAvailable:$true `
-Hidden:$false `
-RunOnlyIfNetworkAvailable:$true `
-ExecutionTimeLimit (New-TimeSpan -Hours 2)
Register-ScheduledTask -TaskName "<<TASK_NAME>>_Cond" `
-TaskPath "<<TASK_PATH>>\Conditional" `
-Action $action -Trigger $trigger -Settings $settings `
-User "<<USERNAME>>" -Description "Task condizionale (richiede rete / alimentazione AC)"
Esempi di condizioni
| Condizione | Impostazione | Descrizione |
|---|---|---|
| Solo a corrente | -AllowStartIfOnBatteries:$false |
Non partire a batteria |
| Rete obbligatoria | -RunOnlyIfNetworkAvailable:$true |
Non eseguire senza rete |
| Solo in idle | Via XML o COM | Supporto nativo PowerShell limitato |
| Timeout massimo | -ExecutionTimeLimit |
Evita esecuzioni bloccate |
| Retry | XML o trigger ripetuti | Alcuni limiti in modalità solo PowerShell |
Step 4: Gestione dei task esistenti
# Elenca i task
Get-ScheduledTask | Where-Object TaskPath -like "<<TASK_PATH>>*"
# Abilita / disabilita
Enable-ScheduledTask -TaskName "<<TASK_NAME>>"
Disable-ScheduledTask -TaskName "<<TASK_NAME>>"
# Stato di esecuzione
Get-ScheduledTaskInfo -TaskName "<<TASK_NAME>>" |
Select-Object TaskName, NextRunTime, LastRunTime, LastTaskResult
Abilitare il registro operativo (Operational Log)
Il canale Microsoft-Windows-TaskScheduler/Operational può essere disabilitato di default.
Abilitarlo per troubleshooting e audit:
wevtutil sl Microsoft-Windows-TaskScheduler/Operational /e:true
Step 5: Troubleshooting e verifica log
# Ultimo esito di esecuzione
Get-ScheduledTaskInfo -TaskName "<<TASK_NAME>>"
# Log operativo filtrato per nome task
Get-WinEvent -LogName "Microsoft-Windows-TaskScheduler/Operational" -MaxEvents 50 |
Where-Object { $_.Message -match "<<TASK_NAME>>" } |
Select-Object TimeCreated, Id, Message | Format-Table -AutoSize
Cause frequenti e rimedi
| Causa | Rimedio |
|---|---|
| Privilegi insufficienti | Rivedere i diritti dell’account / usare account di servizio |
| Execution Policy restrittiva | Script firmati o -ExecutionPolicy Bypass in ambienti controllati |
TaskPath / descrizione mancanti |
Impostare -TaskPath e -Description per chiarezza |
| Trigger evento non attivo | Verificare XML e filtro eventi |
| Conflitti tra trigger/condizioni | Riesaminare la logica di trigger e Settings |
Step 6: Raccomandazioni
- Eseguire come SYSTEM o con account di servizio dedicato, rispettando il principio del minimo privilegio.
- Implementare log ed eccezioni nello script per tracciare successi/fallimenti.
- Templatizzare le definizioni XML e versionarle (GitHub, ecc.).
- Monitorare periodicamente con
Get-ScheduledTaskInfoe configurare alert per anomalie. - Rimuovere i task inutili con
Unregister-ScheduledTaskper mantenere ordinata la Libreria.
Conclusione
Il Task Scheduler, oltre alla semplice pianificazione, abilita un’automazione potente grazie a trigger su eventi, condizioni di esecuzione e integrazione con PowerShell.
Registrazione, gestione e monitoraggio “as-code” aumentano ripetibilità, governabilità e sicurezza operativa.
