How to Schedule a PowerShell Script in Task Scheduler
Scheduling a PowerShell script in Task Scheduler is the simplest way to make a routine run on its own: export a CSV every morning, clean up logs on Sundays, or call an API every hour. No extra infrastructure is needed — Task Scheduler already ships with Windows. What follows is the full walkthrough, including the classic error that makes the task look like it ran while producing nothing.
Prerequisites
- Windows 10/11 or Windows Server, with Task Scheduler.
- A
.ps1script you have already tested by hand in the console. - Administrator permissions (required for tasks that run without a logged-on session).
- Windows PowerShell 5.1 (
powershell.exe) or PowerShell 7 (pwsh.exe).
Step 1: Prepare the script to run unattended
A script that works in your console can fail silently once it is scheduled: it runs from a different working directory, with no profile loaded and nobody around to answer prompts. Two rules will save you hours of debugging — always use absolute paths, and write a log.
# C:\Scripts\ExportarVendas.ps1
$ErrorActionPreference = 'Stop'
$log = 'C:\Scripts\logs\exportar-vendas.log'
New-Item -ItemType Directory -Path (Split-Path $log) -Force | Out-Null
try {
"$(Get-Date -Format s) - inicio" | Add-Content $log
$dados = Import-Csv 'C:\Dados\vendas.csv'
$dados | Where-Object { [decimal]$_.Total -gt 100 } |
Export-Csv 'C:\Dados\vendas_top.csv' -NoTypeInformation -Encoding UTF8
"$(Get-Date -Format s) - OK ($($dados.Count) linhas)" | Add-Content $log
exit 0
}
catch {
"$(Get-Date -Format s) - ERRO: $($_.Exception.Message)" | Add-Content $log
exit 1
}
Note the exit 0 and exit 1: that is how the script reports success or failure to Task Scheduler, which surfaces them in the Last Run Result column.
Step 2: Create the task in the GUI
Open Task Scheduler (taskschd.msc) and pick Create Task — not Create Basic Task, because the latter does not expose the options that matter here.
- General: name the task, then tick Run whether user is logged on or not and Run with highest privileges.
- Triggers → New → Daily, at 07:00.
- Actions → New → Start a program:
- Program/script:
powershell.exe - Add arguments:
-NoProfile -ExecutionPolicy Bypass -File "C:\Scripts\ExportarVendas.ps1" - Start in:
C:\Scripts
- Program/script:
The path to the.ps1always goes inside-Fileand in quotes. If you put it directly in the Program/script field, Windows will try to open it in an editor instead of running it.
Step 3: Create the same task with PowerShell
If you need to repeat this on ten servers, do it in code. The ScheduledTasks module is already installed on Windows.
$acao = New-ScheduledTaskAction -Execute 'powershell.exe' -Argument '-NoProfile -ExecutionPolicy Bypass -File "C:\Scripts\ExportarVendas.ps1"' -WorkingDirectory 'C:\Scripts'
$gatilho = New-ScheduledTaskTrigger -Daily -At 07:00
$definicoes = New-ScheduledTaskSettingsSet -StartWhenAvailable -MultipleInstances IgnoreNew -ExecutionTimeLimit (New-TimeSpan -Hours 1)
$params = @{
TaskName = 'Exportar Vendas'
TaskPath = '\bConcepts\'
Action = $acao
Trigger = $gatilho
Settings = $definicoes
User = 'SYSTEM'
RunLevel = 'Highest'
Force = $true
}
Register-ScheduledTask @params
The SYSTEM account always runs, with no password and no logged-on session — ideal when the script only touches local files. If you need to reach a network share or a database using integrated authentication, register the task with a domain service account (-User 'DOMINIO\svc_dados' -Password '...') and grant it permissions on those resources.
For PowerShell 7, swap the executable for 'C:\Program Files\PowerShell\7\pwsh.exe'; the arguments stay the same.
Step 4: Avoid the Execution Policy error
This is the most commonly reported error: the task finishes in seconds, the log stays empty, and Event Viewer shows File cannot be loaded because running scripts is disabled on this system. The cause is the machine's Execution Policy.
The -ExecutionPolicy Bypass parameter fixes it for that process only — it does not change the computer's policy or weaken global security. -NoProfile, in turn, prevents the user profile (which may not even exist for a service account) from loading and changing variables or the current folder.
Step 5: Test without waiting for the schedule
Do not wait until 07:00 to find out whether it works. Force an immediate run:
Start-ScheduledTask -TaskName 'Exportar Vendas' -TaskPath '\bConcepts\'
Verify the result
Check the three usual signals — the exit code, the script log, and the file produced:
Get-ScheduledTaskInfo -TaskName 'Exportar Vendas' -TaskPath '\bConcepts\' |
Select-Object LastRunTime, LastTaskResult, NextRunTime
Get-Content 'C:\Scripts\logs\exportar-vendas.log' -Tail 5
How to read LastTaskResult:
- 0 — success (the script returned
exit 0). - 1 — the script caught an error and returned
exit 1: check the log. - 0x41301 — the task is still running.
- 0x41303 — the task has never run.
If you need more detail, the scheduler's own history lives in the Microsoft-Windows-TaskScheduler/Operational event log.
Conclusion
With a well-prepared script (absolute paths, a log, and exit codes) and a task registered in code, you get automation that is reliable and reproducible on any Windows server. The natural next step is to parameterise the script, send an email whenever LastTaskResult is non-zero, and — once the routine has to run outside the local network — move it to an Azure Automation Runbook. One last tip: if the task runs on your laptop, tick Wake the computer to run this task — what good is a schedule if the machine was asleep?