Cómo programar reinicio automático en Windows Server VPS

Aprende a programar reinicio automático en Windows Server con el Programador de tareas y PowerShell, con ventanas de mantenimiento seguras y registros.

Los servidores Windows que ejecutan aplicaciones de larga duración — IIS hospedando APIs, servicios .NET, instancias de SQL Server, pasarelas de integración — se degradan gradualmente sin reinicio. La memoria se fragmenta, los handles del kernel se acumulan, y las actualizaciones pendientes quedan en un estado intermedio que solo un reinicio resuelve. En producción, la práctica estable es programar el reinicio periódico en una ventana de bajo tráfico.

Este tutorial cubre cómo configurar el reinicio automático en un Windows Server VPS mediante el Programador de tareas (interfaz gráfica y línea de comandos) y mediante PowerShell. También muestra cómo añadir avisos para las sesiones RDP activas, condiciones de aborto basadas en carga, y logs auditables para confirmar que cada ventana se ejecutó. Tiempo estimado: 25 minutos.

La audiencia es el sysadmin Windows que ya tiene el servidor configurado y quiere automatizar el ciclo de mantenimiento sin depender de una conexión manual el domingo de madrugada.

Requisitos previos

Requisitos previos

Windows Server 2019, 2022 o 2025 con acceso administrativo (RDP o consola). PowerShell 5.1 o superior (ya viene instalado). La cuenta usada para crear la tarea necesita tener el derecho de inicio de sesión como servicio y el privilegio de apagar el sistema — los administradores locales tienen ambos por defecto.

Antes de empezar, confirma los datos básicos de la sesión. Estos valores se referencian en los comandos de abajo:

Sistema Windows Server 2022
Cuenta Administrator
Shell PowerShell 5.1+
Ventana objetivo Domingo 04:00

Decisión: Programador de tareas o PowerShell

Existen dos caminos para programar el reinicio en Windows. Cada uno cubre un escenario:

MétodoCuándo usarLimitación
Programador vía GUIConfiguración única, el sysadmin prefiere clicDifícil de versionar y replicar
Programador vía schtasksScript único reproducibleSintaxis verbosa para condiciones complejas
PowerShell Register-ScheduledTaskVersionado, lógica condicional, múltiples servidoresCurva de aprendizaje mayor

Para un servidor único, el Programador vía GUI es suficiente. Para una flota de 5+ servidores o si usas configuración como código, PowerShell es el camino. Vamos a cubrir los tres métodos — elige el que encaje.

Método 1: Programador de tareas vía interfaz gráfica

La interfaz gráfica es la forma más rápida para un servidor aislado. Los pasos siguientes crean una tarea que reinicia el servidor todos los domingos a las 4 de la madrugada.

01

Abre el Programador de tareas. Pulsa Win + R, escribe taskschd.msc y pulsa Enter.

En el panel derecho, haz clic en “Crear tarea” (no “Tarea básica” — necesitas las opciones avanzadas).

02

En la pestaña “General”, rellena:

  • Nombre: Reboot Semanal Mantenimiento
  • Descripción: Reinicio automatico de mantenimiento - domingo 04:00
  • Selecciona “Ejecutar con los privilegios más altos”
  • En “Configurar para”, selecciona la versión de tu Windows Server

Marca “Ejecutar tanto si el usuario inició sesión como si no” — esto garantiza la ejecución incluso sin sesión RDP activa.

03

Pestaña “Desencadenadores” → “Nuevo”. Configura:

  • Iniciar la tarea: “Según una programación”
  • Semanalmente, repetir cada 1 semana
  • Día: Domingo
  • Hora: 04:00:00

En las opciones avanzadas, marca “Habilitado” y déjalo sin caducidad.

04

Pestaña “Acciones” → “Nueva”. Configura:

  • Acción: “Iniciar un programa”
  • Programa o script: shutdown.exe
  • Agregar argumentos: /r /t 600 /c "Mantenimiento semanal automatico" /f

El parámetro /r fuerza el reinicio (no apagado), /t 600 da 10 minutos de aviso a los usuarios conectados, /c define el mensaje visible, y /f fuerza el cierre de aplicaciones que no responden.

05

Pestaña “Condiciones”. Desmarca “Iniciar la tarea solo si el equipo está inactivo” e “Iniciar la tarea solo si el equipo está conectado a la corriente alterna”. En un servidor, esas condiciones no tienen sentido y pueden impedir la ejecución.

Pestaña “Configuración”. Marca “Permitir que la tarea se ejecute a petición” y “Si la tarea falla, reiniciarla cada 1 minuto, intentar reiniciar hasta 3 veces”.

Haz clic en OK. Se te pedirá introducir la contraseña de la cuenta — proporciónala.

Pruébala antes de confiar

Haz clic con el botón derecho sobre la tarea creada y selecciona “Ejecutar”. El reinicio debe dispararse con aviso visible. Reconéctate después y confirma que todo arrancó. Una tarea que nunca se probó manualmente suele fallar en la primera ejecución programada.

Método 2: Creación vía schtasks

Para scriptar la misma programación en una línea — útil en provisioning o para documentar la configuración — usa schtasks.

01

Abre PowerShell como administrador (clic derecho → “Ejecutar como administrador”) y ejecuta:

schtasks /create `
  /tn "Reboot Semanal Mantenimiento" `
  /tr "shutdown.exe /r /t 600 /c 'Mantenimiento semanal automatico' /f" `
  /sc weekly /d SUN /st 04:00 `
  /ru "SYSTEM" /rl HIGHEST /f

El parámetro /ru SYSTEM evita la dependencia de la contraseña de una cuenta — la tarea se ejecuta como sistema. /rl HIGHEST garantiza privilegios elevados, y /f sobrescribe si la tarea ya existe.

02

Verifica que la tarea se creó:

schtasks /query /tn "Reboot Semanal Mantenimiento" /v /fo LIST

La salida muestra el próximo horario de ejecución, el estado, y la última ejecución. Confirma que “Próxima ejecución” cae el próximo domingo a las 04:00.

Método 3: PowerShell con lógica condicional

Cuando necesitas condiciones más complejas — abortar el reinicio si la CPU está por encima del 80%, o si un servicio crítico está en una transacción — encapsula la lógica en un script y prográmalo con Register-ScheduledTask.

01

Crea el script envoltorio en C:\Scripts\reboot-semanal.ps1:

$LogPath = "C:\Scripts\reboot-semanal.log"
$Stamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"

# Comprueba carga media de CPU de los ultimos 60s
$cpu = (Get-Counter '\Processor(_Total)\% Processor Time' `
  -SampleInterval 5 -MaxSamples 12).CounterSamples |
  Measure-Object -Property CookedValue -Average

if ($cpu.Average -gt 80) {
    Add-Content $LogPath "$Stamp ABORT cpu=$([math]::Round($cpu.Average,1))%"
    exit 1
}

# Comprueba servicio critico (ajusta el nombre)
$svc = Get-Service -Name "MiServicioCritico" -ErrorAction SilentlyContinue
if ($svc -and $svc.Status -eq 'Running') {
    # Logica de health check de la aplicacion aqui
    Add-Content $LogPath "$Stamp OK servicio activo, continuando"
}

Add-Content $LogPath "$Stamp REBOOT iniciando shutdown /r /t 600"
Start-Process -FilePath "shutdown.exe" `
  -ArgumentList "/r","/t","600","/c","Mantenimiento semanal","/f"

Este script registra en un log local cada ejecución, comprueba la CPU media de 1 minuto, y solo dispara el reinicio si la condición es segura. Ajusta el nombre del servicio y los umbrales a tu escenario.

02

Registra la tarea con PowerShell:

$Action = New-ScheduledTaskAction `
  -Execute "PowerShell.exe" `
  -Argument "-ExecutionPolicy Bypass -File C:\Scripts\reboot-semanal.ps1"

$Trigger = New-ScheduledTaskTrigger `
  -Weekly -DaysOfWeek Sunday -At 04:00

$Principal = New-ScheduledTaskPrincipal `
  -UserId "SYSTEM" -LogonType ServiceAccount -RunLevel Highest

$Settings = New-ScheduledTaskSettingsSet `
  -StartWhenAvailable -DontStopOnIdleEnd `
  -RestartCount 3 -RestartInterval (New-TimeSpan -Minutes 1)

Register-ScheduledTask `
  -TaskName "Reboot Semanal Mantenimiento" `
  -Action $Action -Trigger $Trigger `
  -Principal $Principal -Settings $Settings -Force

La flag -StartWhenAvailable es importante: si el servidor estaba apagado a la hora programada y se enciende después, la tarea se ejecuta en la siguiente oportunidad en lugar de saltarse el ciclo.

Versiona el script en Git

Haz commit de reboot-semanal.ps1 en un repositorio de configuración de tu infraestructura. Cuando necesites ajustar el umbral de CPU o añadir una nueva condición, lo editas una vez y lo replicas vía Group Policy o Ansible. La configuración dispersa en GUI se convierte en deuda técnica en una flota de 5+ servidores.

Verificación

Confirma que la tarea está activa y que la próxima hora es correcta:

Get-ScheduledTask -TaskName "Reboot Semanal Mantenimiento" |
  Select-Object TaskName, State, @{N='Proximo';E={
    (Get-ScheduledTaskInfo $_).NextRunTime
  }}

Salida esperada:

TaskName                       State    Proximo
--------                       -----    -------
Reboot Semanal Mantenimiento   Ready    01/06/2026 04:00:00

Para confirmar que la tarea se ejecutó tras el primer domingo, consulta el historial:

Get-ScheduledTaskInfo -TaskName "Reboot Semanal Mantenimiento"

El campo LastRunTime muestra cuándo se ejecutó y LastTaskResult debe ser 0 (éxito). Cualquier valor distinto indica un fallo — investiga vía Programador → Historial o vía Get-WinEvent en el log “Microsoft-Windows-TaskScheduler/Operational”.

Resolución de problemas

La tarea no se ejecuta, sin mensaje de error

Verifica que el historial del Programador esté habilitado. Por defecto, en algunos Windows Server viene deshabilitado, lo que impide ver lo que ocurrió. En el panel derecho del Programador, haz clic en “Habilitar Historial de Todas las Tareas”.

Después de eso, abre la tarea y mira la pestaña Historial. Si el evento es “La tarea no se inició porque la cuenta no estaba conectada” — olvidaste marcar “Ejecutar tanto si el usuario inició sesión como si no” durante la creación.

El reinicio se dispara pero el servidor no arranca

Verifica si algún servicio con inicio automático está fallando en el arranque. Ejecuta tras reconectarte:

Get-EventLog -LogName System -EntryType Error -Newest 20 |
  Where-Object {$_.Source -like "*Service*"}

Un servicio atascado en estado “Starting” indefinidamente es la causa más común. Suele ser una dependencia de red o base de datos que aún no se ha estabilizado — añade un retraso en el arranque del servicio problemático.

Cuidado con el bucle de reinicio

Si el servidor entra en un bucle de reinicio, conéctate vía consola (no RDP) y deshabilita la tarea antes que nada: Disable-ScheduledTask -TaskName "Reboot Semanal Mantenimiento". En un VPS, la consola es el acceso vía panel de control — RDP no funcionará si la máquina reinicia antes de que la red arranque.

El aviso de reinicio no aparece a los usuarios RDP

El parámetro /c "mensaje" solo funciona si el usuario tiene una sesión activa en el momento en que se ejecuta shutdown /t 600. Si se conecta después del disparo, no se muestra nada. Para una notificación proactiva, añade antes del shutdown:

msg * /TIME:60 "Reinicio programado en 10 minutos - guarda tu trabajo"

msg.exe envía un broadcast a todas las sesiones activas — combinado con el aviso visual de shutdown, cubre ambos casos.

Próximos pasos

Con el ciclo de reinicio automatizado, vale la pena evolucionar en direcciones complementarias:

  • Configura un health check post-reinicio mediante PowerShell que valide los servicios críticos y envíe una alerta si algo no arrancó en 5 minutos.
  • Añade registro en event log (Write-EventLog) en el script envoltorio para centralizar vía syslog o SIEM.
  • Documenta la ventana de mantenimiento en una status page interna para que el equipo de aplicación sepa cuándo esperar indisponibilidad.
  • Combínalo con un snapshot automático previo al reinicio mediante la API de tu proveedor para un rollback rápido si algo falla.
  • Considera programar Windows Update por separado para que se ejecute antes del reinicio, garantizando que el ciclo cubra las actualizaciones pendientes.

Si estás llevando esto a producción, un VPS Hostini Windows Server ya viene con consola fuera de banda en el panel — útil para recuperar el acceso si un reinicio programado rompe la red y RDP queda no disponible, evitando depender del soporte para resetear la máquina.

Preguntas frecuentes

¿Puedo programar un reinicio sin desconectar a los usuarios RDP de inmediato?

Sí. El parámetro /t de shutdown define un retraso en segundos antes del reinicio real, durante el cual los usuarios conectados reciben un aviso visual. Usa /t 600 para dar 10 minutos de margen. Combínalo con /c "mensaje" para explicar el motivo en la notificación.

¿Cómo evito que el reinicio programado se dispare si el servidor está bajo alta carga?

Añade una condición de disparo que comprueba el uso medio de CPU de los últimos minutos mediante PowerShell antes del Restart-Computer. Si supera un umbral, escribe en el event log y aborta. El Programador permite ejecutar un script envoltorio en lugar del shutdown directo.

Windows Update programa reinicios por su cuenta — ¿necesito desactivarlo?

En Windows Server, las actualizaciones automáticas normalmente respetan las horas activas y no reinician solas si usas WSUS o programación manual. Aun así, configura la política "No auto-restart with logged on users" para garantizar que solo tu tarea controla cuándo ocurre el reinicio.

¿Cómo verifico si la tarea se ejecutó realmente la semana pasada?

Abre el Programador, selecciona la tarea y haz clic en la pestaña Historial — cada ejecución queda registrada con timestamp y código de salida. Para una auditoría persistente, activa el registro en event log dentro del script (Write-EventLog) y consulta vía Get-WinEvent.

¿Puedo omitir el reinicio programado si un servicio crítico está en una transacción activa?

Sí, pero necesitas un script envoltorio. Antes del Restart-Computer, consulta el estado del servicio (Get-Service, Get-Process, o una API de health check de la aplicación) y retorna sin reiniciar si la condición no se cumple. Registra la decisión para poder rastrearla después.

¿Cuál es el impacto real de no reiniciar un Windows Server durante meses?

La memoria se fragmenta, los handles del kernel se acumulan, el pool no paginado crece y las actualizaciones pendientes quedan en estado intermedio. Las aplicaciones .NET de uptime largo muestran degradación perceptible después de 30-60 días. Reiniciar cada semana o quincena es el equilibrio habitual en producción.

Temas:
Próximos pasos Cloud Ryzen con NVMe y protección DDoS siempre activa.Pon en producción en un VPS Hostini →
¿Te resultó útil este tutorial?
Hablar por WhatsApp