PowerShell Scheduled Tasks
The ScheduledTasks module builds tasks from parts. New-ScheduledTaskAction defines what runs, New-ScheduledTaskTrigger defines when, New-ScheduledTaskPrincipal defines who as, and Register-ScheduledTask assembles and registers them.
Documentation: Microsoft Learn
Overview
The action is where scheduled PowerShell goes wrong. Point -Execute at pwsh.exe or powershell.exe and put the script in -Argument, with -NoProfile and -File. -NoProfile matters because a profile that works interactively can hang or fail in a non-interactive session. Use an absolute path; the working directory is not what you assume.
Under the account the task runs as, the environment is different from yours: different profile, different module path, possibly no mapped drives. A script that works when you run it and fails on schedule is almost always this. Map network paths by UNC rather than drive letter.
Get-ScheduledTaskInfo gives you the last run time and the last result code. That is the first place to look when a task quietly stopped working, and 0x41303 there simply means it has never run.
Start-ScheduledTask triggers a run immediately, which is how you test without waiting for two in the morning.
Inspect this example’s structure
Read the command and its supplied arguments. This example requires real PowerShell or its module; this diagram does not execute it.
$task = [pscustomobject]@{
TaskName = 'NightlyReport'
Action = 'pwsh.exe -NoProfile -File C:\Scripts\Report.ps1'
Trigger = 'Daily 02:00'
Principal = 'svc-Reporting$ (gMSA)'
RunLevel = 'Highest'
}
$task | Format-List- Stage 1$task
Positional values or no named parameters - Stage 2Format-List
Positional values or no named parameters
An example to inspect
Preview the example. Sign in for the full lesson and activities.
$task = [pscustomobject]@{
TaskName = 'NightlyReport'
Action = 'pwsh.exe -NoProfile -File C:\Scripts\Report.ps1'
Trigger = 'Daily 02:00'
Principal = 'svc-Reporting$ (gMSA)'
RunLevel = 'Highest'
}
$task | Format-ListWhat happens
This prints the four parts of a task definition. The Action value shows the pattern that survives being scheduled: the executable, -NoProfile, -File and an absolute path. Principal is a managed service account rather than a person, so nobody's password expiry breaks the job.
Worth remembering
- Build from Action, Trigger and Principal, then Register-ScheduledTask.
- Use -NoProfile and an absolute script path.
- The task account's environment differs from yours. Use UNC, not drive letters.
- Get-ScheduledTaskInfo shows last run time and result code.
Primary documentation
Try it
Illustrative output · values vary by environment
Example reader
Inspect this page's example
Run supported commands against the practice data, or inspect the example without executing it.
Ready to inspect.
Prints the four parts of a scheduled task definition.
Show reference output
Illustrative output · values vary by environment
TaskName : NightlyReport Action : pwsh.exe -NoProfile -File C:\Scripts\Report.ps1 Trigger : Daily 02:00 Principal : svc-Reporting$ (gMSA) RunLevel : Highest