Task Scheduler is the Windows equivalent of cron — and just as essential. This guide creates a scheduled task via the GUI quickly, then shows the PowerShell equivalent so you can script it.
Prerequisites
- Windows Server 2019 / 2022 with admin PowerShell.
- A script to run — we will use
C:\Scripts\nightly-cleanup.ps1as the example.
Step 1: Write the script
C:\Scripts\nightly-cleanup.ps1:
$Log = "C:\Logs\nightly-cleanup.log"
"$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') Cleanup started" | Out-File $Log -Append
# Purge IIS logs older than 30 days
Get-ChildItem 'C:\inetpub\logs\LogFiles' -Recurse -Include '*.log' |
Where-Object LastWriteTime -lt (Get-Date).AddDays(-30) |
Remove-Item -Force -ErrorAction SilentlyContinue
"$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') Cleanup finished" | Out-File $Log -Append
Test it manually first:
powershell.exe -NoProfile -ExecutionPolicy Bypass -File C:\Scripts\nightly-cleanup.ps1
Get-Content C:\Logs\nightly-cleanup.log -Tail 5
Step 2: Create the scheduled task via PowerShell
$Action = New-ScheduledTaskAction `
-Execute 'powershell.exe' `
-Argument '-NoProfile -ExecutionPolicy Bypass -File "C:\Scripts\nightly-cleanup.ps1"'
$Trigger = New-ScheduledTaskTrigger -Daily -At 02:30AM
$Settings = New-ScheduledTaskSettingsSet `
-StartWhenAvailable `
-DontStopIfGoingOnBatteries `
-RunOnlyIfNetworkAvailable:$false `
-RestartCount 3 -RestartInterval (New-TimeSpan -Minutes 5)
$Principal = New-ScheduledTaskPrincipal `
-UserId "SYSTEM" `
-LogonType ServiceAccount `
-RunLevel Highest
Register-ScheduledTask `
-TaskName "Nightly IIS log cleanup" `
-Description "Purges IIS log files older than 30 days" `
-Action $Action `
-Trigger $Trigger `
-Settings $Settings `
-Principal $Principal
Step 3: Verify and run on demand
Get-ScheduledTask -TaskName "Nightly IIS log cleanup" |
Get-ScheduledTaskInfo
# Force-run it now to confirm it actually works
Start-ScheduledTask -TaskName "Nightly IIS log cleanup"
# Check it ran
Get-ScheduledTask -TaskName "Nightly IIS log cleanup" |
Get-ScheduledTaskInfo |
Format-List LastRunTime, LastTaskResult, NumberOfMissedRuns
LastTaskResult should be 0. Anything else, check the script's log file and the Event Viewer (Applications and Services Logs → Microsoft → Windows → TaskScheduler → Operational).
Step 4: Schedule on a non-time trigger
At Windows logon:
$Trigger = New-ScheduledTaskTrigger -AtLogOn -User "CORP\ops"
At system startup:
$Trigger = New-ScheduledTaskTrigger -AtStartup
On an event (e.g. when service MyService stops):
$EventQuery = @"
<QueryList>
<Query Id="0" Path="System">
<Select Path="System">*[System[Provider[@Name='Service Control Manager'] and EventID=7036]]</Select>
</Query>
</QueryList>
"@
$Trigger = New-CimInstance -ClassName MSFT_TaskEventTrigger -Namespace Root/Microsoft/Windows/TaskScheduler `
-ClientOnly -Property @{ Enabled = $true; Subscription = $EventQuery }
Step 5: Export and version-control
Export-ScheduledTask -TaskName "Nightly IIS log cleanup" |
Out-File "C:\Repos\ops\tasks\nightly-iis-cleanup.xml" -Encoding UTF8
Import elsewhere:
Register-ScheduledTask -TaskName "Nightly IIS log cleanup" `
-Xml (Get-Content "C:\Repos\ops\tasks\nightly-iis-cleanup.xml" -Raw) `
-User "SYSTEM" -Force
Verify
Get-ScheduledTask | Where-Object State -ne "Disabled" | Format-Table TaskName, State
Get-WinEvent -LogName "Microsoft-Windows-TaskScheduler/Operational" -MaxEvents 20 |
Select-Object TimeCreated, Id, Message
Conclusion
Task Scheduler beats cron in two places: rich triggers (on event, at logon, on idle), and per-task identity (Run as SYSTEM, a service account, or only when the user is signed in). It loses on simplicity — but New-ScheduledTask* makes it scriptable.
Next steps
- Install the OS itself with Install Windows Server 2022.
- For inbound rules see Windows Firewall via PowerShell.
- Set up web hosting with IIS Web Server on Windows.
Comments
0 total · 0 threads