Cómo crear un Servicio de Windows con PowerShell: paso a paso
Crear un Servicio de Windows con PowerShell permite ejecutar scripts o aplicaciones en segundo plano como servicios gestionados por el Service Control Manager. Este proceso es útil para automatizar tareas que deben ejecutarse siempre que el sistema arranque o para tener mejor control sobre el arranque/parada, reinicio y dependencias.
Requisitos previos
- Windows 10/11 o Windows Server con permisos de administrador.
- PowerShell 5.1 o PowerShell 7+ (para crear y gestionar archivos y servicios).
- Un script PowerShell o un ejecutable simple para ejecutar como servicio (ej.: script.ps1).
Paso 1: Preparar un wrapper simple en PowerShell
Los Servicios de Windows esperan un ejecutable. El enfoque simple es usar un pequeño wrapper que ejecute su script en bucle y responda a señales de parada. Vamos a crear un archivo llamado ServiceWrapper.ps1 que gestione arranque/parada y registre eventos básicos.
# ServiceWrapper.ps1
param(
[string]$ScriptToRun = "C:\path\to\script.ps1",
[int]$IntervalSeconds = 60
)
$stopRequested = $false
# Capturar Ctrl+C/Stop
Register-ObjectEvent -InputObject $Host -EventName 'CancelKeyPress' -Action { $global:stopRequested = $true } | Out-Null
Write-EventLog -LogName Application -Source "MyPowerShellService" -EntryType Information -EventId 1000 -Message "Service starting"
while (-not $stopRequested) {
try {
& powershell -NoProfile -NonInteractive -ExecutionPolicy Bypass -File $ScriptToRun
}
catch {
Write-EventLog -LogName Application -Source "MyPowerShellService" -EntryType Error -EventId 1001 -Message "Script error: $_"
}
Start-Sleep -Seconds $IntervalSeconds
}
Write-EventLog -LogName Application -Source "MyPowerShellService" -EntryType Information -EventId 1002 -Message "Service stopping"
Paso 2: Crear un ejecutable launcher con PowerShell
Para registrar un servicio es más práctico tener un pequeño launcher exe. Podemos usar la utilidad sc.exe para apuntar a una instancia de cmd.exe que invoque PowerShell. Esto evita herramientas externas. Aquí creamos el servicio para ejecutar cmd.exe /c powershell -File ServiceWrapper.ps1.
# Abrir PowerShell como Administrador y ejecutar:
$serviceName = "MyPowerShellService"
$displayName = "My PowerShell Service"
$wrapperPath = 'C:\services\ServiceWrapper.ps1' # ruta absoluta
$cmd = "C:\Windows\System32\cmd.exe /c powershell -NoProfile -NonInteractive -ExecutionPolicy Bypass -File `"$wrapperPath`""
sc.exe create $serviceName binPath= "$cmd" start= auto DisplayName= "$displayName"
# Conceder permiso para escribir en el Event Log (opcional, si usa Write-EventLog)
New-EventLog -LogName Application -Source "MyPowerShellService" -ErrorAction SilentlyContinue
Paso 3: Configurar cuenta y dependencias del servicio
Por defecto el servicio se ejecuta como LocalSystem. Si el script necesita red o una cuenta específica, cambie la cuenta con sc.exe config. También puede añadir dependencias con la etiqueta depend=.
# Ejemplo: configurar para usar una cuenta de dominio
sc.exe config MyPowerShellService obj= "DOMAIN\ServiceUser" password= "P@ssw0rd"
# Ejemplo: añadir dependencia en el servicio de red
sc.exe config MyPowerShellService depend= Tcpip/WinSock
Paso 4: Controlar el servicio (iniciar, parar, reiniciar)
Use comandos simples para gestionar el servicio. En caso de problemas, compruebe el Event Viewer y los archivos de log de su script.
# Iniciar el servicio
Start-Service -Name MyPowerShellService
# Comprobar estado
Get-Service -Name MyPowerShellService | Format-List Name,Status,ServiceType
# Parar el servicio
Stop-Service -Name MyPowerShellService -Force
# Reiniciar
Restart-Service -Name MyPowerShellService
Verificar el resultado
Confirme que el servicio aparece y se ejecuta como se espera: Get-Service muestra Status = Running. Revise el Event Viewer (Application) para entradas con Source = MyPowerShellService y los EventId 1000/1002. Si su script escribe archivos de log, confirme que se actualizan según el IntervalSeconds.
Conclusión
Ahora tiene un Servicio de Windows básico que ejecuta un script PowerShell en segundo plano y que responde a arranque/parada. Siguientes pasos: proteger credenciales con el Windows Credential Manager, crear logs más robustos o empaquetar el wrapper como un EXE con herramientas como PS2EXE para mayor control. Consejo: pruebe siempre el wrapper manualmente antes de registrar el servicio para evitar bucles no deseados.