(+351) 21 24 10006  ·  info@bconcepts.pt
Carnaxide, Lisboa

Cómo programar un script de PowerShell en Task Scheduler

João Barros 14 de July de 2026 5 min de lectura

Programar un script de PowerShell en Task Scheduler es la forma más sencilla de dejar una rutina funcionando sola: exportar un CSV cada mañana, limpiar logs los domingos o llamar a una API cada hora. No hace falta infraestructura adicional — el Programador de tareas ya viene con Windows. A continuación tienes el paso a paso completo, incluido el error clásico que hace que la tarea parezca haberse ejecutado sin producir nada.

Requisitos previos

  • Windows 10/11 o Windows Server, con Task Scheduler.
  • Un script .ps1 ya probado a mano en la consola.
  • Permisos de administrador (necesarios para tareas que se ejecutan sin sesión iniciada).
  • Windows PowerShell 5.1 (powershell.exe) o PowerShell 7 (pwsh.exe).

Paso 1: Preparar el script para ejecutarse desatendido

Un script que funciona en tu consola puede fallar en silencio al programarse: se ejecuta desde otro directorio de trabajo, sin perfil cargado y sin nadie que responda a las preguntas. Dos reglas te ahorrarán horas de depuración — usa siempre rutas absolutas y escribe un 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
}

Fíjate en exit 0 y exit 1: así es como el script comunica éxito o fallo a Task Scheduler, que los muestra en la columna Last Run Result.

Paso 2: Crear la tarea en la interfaz gráfica

Abre el Programador de tareas (taskschd.msc) y elige Create Task — no Create Basic Task, porque esta última no permite configurar las opciones que importan.

  1. General: pon nombre a la tarea y marca Run whether user is logged on or not y Run with highest privileges.
  2. Triggers → New → Daily, a las 07:00.
  3. Actions → New → Start a program:
    • Program/script: powershell.exe
    • Add arguments: -NoProfile -ExecutionPolicy Bypass -File "C:\Scripts\ExportarVendas.ps1"
    • Start in: C:\Scripts
La ruta del .ps1 va siempre dentro de -File y entre comillas. Si la pones directamente en el campo Program/script, Windows intentará abrirlo en el editor en lugar de ejecutarlo.

Paso 3: Crear la misma tarea con PowerShell

Si necesitas repetir esto en diez servidores, hazlo por código. El módulo ScheduledTasks ya viene instalado en 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

La cuenta SYSTEM siempre se ejecuta, sin contraseña y sin sesión iniciada — ideal cuando el script solo toca ficheros locales. Si necesitas acceder a un recurso compartido de red o a una base de datos con autenticación integrada, registra la tarea con una cuenta de servicio del dominio (-User 'DOMINIO\svc_dados' -Password '...') y concédele permisos sobre esos recursos.

Para PowerShell 7, cambia el ejecutable por 'C:\Program Files\PowerShell\7\pwsh.exe'; los argumentos son los mismos.

Paso 4: Evitar el error de Execution Policy

Este es el error más reportado: la tarea termina en segundos, el log queda vacío y en el Visor de eventos aparece File cannot be loaded because running scripts is disabled on this system. La causa es la Execution Policy de la máquina.

El parámetro -ExecutionPolicy Bypass lo resuelve solo para ese proceso — no cambia la política del equipo ni debilita la seguridad global. -NoProfile, por su parte, evita que se cargue el perfil del usuario (que puede ni existir en la cuenta de servicio) y cambie variables o la carpeta actual.

Paso 5: Probar sin esperar al horario

No esperes a las 07:00 para saber si funciona. Fuerza una ejecución inmediata:

Start-ScheduledTask -TaskName 'Exportar Vendas' -TaskPath '\bConcepts\'

Verificar el resultado

Comprueba las tres señales habituales — el código de salida, el log del script y el fichero producido:

Get-ScheduledTaskInfo -TaskName 'Exportar Vendas' -TaskPath '\bConcepts\' |
    Select-Object LastRunTime, LastTaskResult, NextRunTime

Get-Content 'C:\Scripts\logs\exportar-vendas.log' -Tail 5

Cómo interpretar LastTaskResult:

  • 0 — éxito (el script hizo exit 0).
  • 1 — el script capturó un error e hizo exit 1: revisa el log.
  • 0x41301 — la tarea sigue en ejecución.
  • 0x41303 — la tarea nunca se ha ejecutado.

Si necesitas más detalle, el historial del propio programador está en el registro de eventos Microsoft-Windows-TaskScheduler/Operational.

Conclusión

Con un script bien preparado (rutas absolutas, log y códigos de salida) y una tarea registrada por código, tienes una automatización fiable y replicable en cualquier servidor Windows. El siguiente paso natural es parametrizar el script, enviar un email cuando LastTaskResult sea distinto de cero y, cuando la rutina tenga que ejecutarse fuera de la red local, moverla a un Azure Automation Runbook. Un último consejo: si la tarea corre en tu portátil, marca Wake the computer to run this task — ¿de qué sirve programarla si la máquina estaba suspendida?