Get in touch: kontakt@msadura.pl

The Ultimate Homelab Power Outage Orchestrator: Complete Automation with NUT, PowerShell, and vSphere

Every homelabber fears the sudden click of a UPS kicking into battery mode. When you run a complex infrastructure, a hard power cut can corrupt a storage array, ruin backups, or cause split-brain scenarios in high-availability clusters. The goal of this project is to achieve absolute peace of mind: a fully automated, intelligent orchestration system that gracefully tears down the entire environment during an extended outage, and safely brings it back online when power is restored.My physical homelab consists of a 4-node VMware ESXi cluster running on Minisforum hardware, a QNAP NAS for storage, a Windows Server 2025 handling Veeam backups, and a CyberPower UPS. The „brain” of this operation is a NUT (Network UPS Tools) server installed directly on a Debian Linux environment.

This guide breaks down exactly how to configure the logic, the scripts, and the fail-safes to ensure your data remains protected.

The Orchestration Master Plan

To avoid shutting down the datacenter during minor voltage drops, the system follows a strict chronological logic:

    • 0:00 (Power Loss): The UPS switches to battery, and Debian logs the event.
    • 0:00 – 0:59 (The Grace Period): The NUT scheduler (upssched) starts a 60-second countdown named „ewakuacja”. If the power blinks and returns within this window, the timer is instantly canceled, and the homelab continues running uninterrupted.
    • 1:00 (Evacuation Begins): The timer finishes, triggering the main shutdown-homelab.sh script. Veeam and ESXi are safely shut down, massively dropping the wattage load on the UPS to preserve its remaining capacity.
    • 3:06 (Storage Teardown): Debian connects to the QNAP NAS via SSH and commands it to power off safely, spinning down the drives.
    • 4:01 (The Killpower Command): A hardware timer in the UPS reaches zero, physically cutting power to the rack outlets to freeze the homelab in a safe state, even if grid power returns midway through the process.
    • Resurrection: Once grid power returns, the UPS restores outlet power. The QNAP boots, loads Debian, waits for stability, and automatically sends Wake-On-LAN (WOL) magic packets to the ESXi hosts and the Veeam server to bring the environment back online.

Phase 1: Configuring the NUT Server

First, install the Network UPS Tools and SNMP packages on your Debian host:

BASH
apt update && apt install nut nut-snmp

Next, define your UPS connection parameters in /etc/nut/ups.conf:

/etc/nut/ups.conf
[cyberpower] 
driver = snmp-ups 
port = 0.0.0.0
community = public 
snmp_version = v2c 
mibs = auto 
snmp_timeout = 5 
snmp_retries = 3

Create a highly privileged admin user in /etc/nut/upsd.users:

/etc/nut/upsd.users
[admin] 
password = xxx
actions = SET 
instcmds = ALL 
upsmon master

Tell the NUT monitor to watch this UPS in /etc/nut/upsmon.conf:

/etc/nut/upsmon.conf
MONITOR cyberpower@localhost 1 admin xxx master 
MINSUPPLIES 1 
SHUTDOWNCMD "/usr/local/bin/shutdown-homelab.sh" 
POLLFREQ 5 
POLLFREQALERT 1 
HOSTSYNC 15

Phase 2: Preparing Dependencies (PowerCLI and SSH)

To allow Debian to natively command the VMware environment, we need to install PowerShell and the VMware PowerCLI module directly on Linux.

Install PowerShell 7.4.2 and its dependencies:

BASH
apt-get install -y libunwind8 libicu-dev curl
curl -L -o /tmp/powershell.tar.gz https://github.com/PowerShell/PowerShell/releases/download/v7.4.2/powershell-7.4.2-linux-x64.tar.gz 
mkdir -p /opt/microsoft/powershell/7 
tar zxf /tmp/powershell.tar.gz -C /opt/microsoft/powershell/7 
chmod +x /opt/microsoft/powershell/7/pwsh 
ln -s /opt/microsoft/powershell/7/pwsh /usr/bin/pwsh

Install VMware PowerCLI and disable telemetry/certificate warnings:

BASH
pwsh -Command "Install-Module -Name VMware.PowerCLI -Scope CurrentUser -Force"
pwsh -Command "Set-PowerCLIConfiguration -InvalidCertificateAction Ignore -ParticipateInCEIP \$false -Confirm:\$false -Scope User"

Generate an RSA key pair (ssh-keygen -t rsa -b 4096) and copy it to your QNAP (ssh-copy-id admin@0.0.0.0) for passwordless execution. Do the same for your Windows Server hosting Veeam after installing the OpenSSH feature (Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0) and placing the public key in C:\ProgramData\ssh dministrators_authorized_keys.

Phase 3: The Shutdown Sequence

We split the logic into two scripts. The first handles the delicate VMware environment.

Create /usr/local/bin/shutdown-vmware.ps1:

POWERSHELL: /usr/local/bin/shutdown-vmware.ps1
$vCenterIP = "0.0.0.0"
$vCenterUser = "administrator@xxx.local"
$vCenterPass = "HasloDoVCenter"
$vCenterVMName = "XXX" 

Write-Host "1. Laczenie z vCenter..."
Connect-VIServer -Server $vCenterIP -User $vCenterUser -Password $vCenterPass

Write-Host "2. Zamykanie wszystkich maszyn wirtualnych (oprocz vCenter i vCLS)..."
$vms = Get-VM | Where-Object { $_.PowerState -eq "PoweredOn" -and $_.Name -notmatch "vCLS" -and $_.Name -ne $vCenterVMName }
if ($vms) {
    $vms | Stop-VMGuest -Confirm:$false
    Write-Host "Czekam 3 minuty na bezpieczne zamkniecie systemow operacyjnych..."
    Start-Sleep -Seconds 180
}

Write-Host "3. Zamykanie samego vCenter..."
Get-VM -Name $vCenterVMName | Stop-VMGuest -Confirm:$false
Write-Host "Czekam 2 minuty na zgasniecie vCenter..."
Start-Sleep -Seconds 120

Write-Host "4. Przechodzenie na bezposrednie zamykanie hostow ESXi (Minisforum)..."
$hosts = Get-VMHost | Where-Object { $_.ConnectionState -eq "Connected" }
foreach ($esxi in $hosts) {
    Write-Host "Wysylam sygnal zamkniecia do hosta: $($esxi.Name)"
    Stop-VMHost -VMHost $esxi -Force -Confirm:$false
}
Disconnect-VIServer -Server * -Force -Confirm:$false

Now, create the master orchestrator script at /usr/local/bin/shutdown-homelab.sh:

BASH: /usr/local/bin/shutdown-homelab.sh
#!/bin/bash
LOGFILE="/var/log/homelab-shutdown.log"
QNAP_IP="0.0.0.0"
VEEAM_IP="0.0.0.0"

echo "$(date) - START PROCEDURY SHUTDOWNU ZASILANIA!" >> $LOGFILE

echo "$(date) - 1. Wysylam sygnal zamkniecia do serwera Veeam (Windows)..." >> $LOGFILE
ssh Administrator@$VEEAM_IP "shutdown /s /t 10 /c "NUT Power Outage - Bezpieczne zamykanie" /d p:0:0" >> $LOGFILE 2>&1
sleep 30

echo "$(date) - 2. Uruchamiam skrypt gaszenia VMware i vSAN..." >> $LOGFILE
pwsh -File /usr/local/bin/shutdown-vmware.ps1 >> $LOGFILE 2>&1

echo "$(date) - Czekam 2 minuty przed zamknieciem macierzy (QNAP)..." >> $LOGFILE
sleep 120

echo "$(date) - 3. Wysylam sygnal poweroff do QNAP..." >> $LOGFILE
ssh admin@$QNAP_IP "/sbin/poweroff" >> $LOGFILE 2>&1

Make both scripts executable using chmod +x.

Phase 4: The 60-Second Delay Logic (upssched)

To prevent the homelab from shutting down during a 10-second power blip, configure upssched.
Add these flags to /etc/nut/upsmon.conf:

/etc/nut/upsmon.conf
NOTIFYCMD /sbin/upssched
NOTIFYFLAG ONLINE SYSLOG+WALL+EXEC 
NOTIFYFLAG ONBATT SYSLOG+WALL+EXEC

Define the timer behavior in /etc/nut/upssched.conf:

/etc/nut/upssched.conf
CMDSCRIPT /usr/local/bin/upssched-cmd
PIPEFN /run/nut/upssched.pipe
LOCKFN /run/nut/upssched.lock
AT ONBATT * START-TIMER ewakuacja 60
AT ONLINE * CANCEL-TIMER ewakuacja

Create the trigger script /usr/local/bin/upssched-cmd:

BASH: /usr/local/bin/upssched-cmd
#!/bin/bash
case $1 in
    ewakuacja)
        echo "$(date) - upssched: Minelo 60 sekund od zaniku zasilania! Uruchamiam zamykanie..." >> /var/log/homelab-shutdown.log
        /usr/local/bin/shutdown-homelab.sh
        ;;
    *)
        logger -t upssched-cmd "Nieznana komenda: $1"
        ;;
esac

(Remember to run chmod +x /usr/local/bin/upssched-cmd and systemctl restart nut-monitor.service).

Phase 5: The Automated Resurrection

A good outage orchestrator also handles the recovery. By installing the wakeonlan package (apt-get install -y wakeonlan), Debian can broadcast magic packets to wake the servers in a specific order.

Create /usr/local/bin/startup-homelab.sh:

BASH: /usr/local/bin/startup-homelab.sh
#!/bin/bash
LOGFILE="/var/log/homelab-startup.log"
echo "$(date) - ZASILANIE PRZYWROCONE. URUCHAMIAM PROCEDURY..." >> $LOGFILE

# Wait for QNAP to mount RAID and initialize iSCSI/Networking
echo "$(date) - 1/4: Czekam 120s na pelna gotowosc QNAP..." >> $LOGFILE
sleep 120

# Wake up ESXi Minisforum nodes
echo "$(date) - 2/4: Budze hosty ESXi (WoL)..." >> $LOGFILE
wakeonlan -i 10.100.250.255 58:47:ca:7e:ba:fa >> $LOGFILE 2>&1
wakeonlan -i 10.100.250.255 58:47:ca:7e:b9:de >> $LOGFILE 2>&1
wakeonlan -i 10.100.250.255 58:47:ca:7e:b8:8e >> $LOGFILE 2>&1
wakeonlan -i 10.100.250.255 38:05:25:36:0c:e4 >> $LOGFILE 2>&1

# Crucial delay for vSphere Startup (Kernel load, vSAN formation, vCenter boot)
echo "$(date) - 3/4: Hosty wstaja. Czekam 300s (5 min) na sformowanie klastra vSAN..." >> $LOGFILE
sleep 300

# Finally, wake the Veeam Backup Server
echo "$(date) - 4/4: Budze serwer Veeam (WoL)..." >> $LOGFILE
wakeonlan -i 10.100.100.255 38:05:25:36:2E:03 >> $LOGFILE 2>&1

Make the script executable (chmod +x), and automate it by creating a Systemd unit file at /etc/systemd/system/homelab-startup.service:

/etc/systemd/system/homelab-startup.service
[Unit] 
Description=HomeLab Wake-on-LAN Startup Sequencer 
After=network-online.target 
Wants=network-online.target 

[Service] 
Type=oneshot 
ExecStart=/usr/local/bin/startup-homelab.sh 
RemainAfterExit=yes 

[Install] 
WantedBy=multi-user.target

Enable the service with systemctl daemon-reload and systemctl enable homelab-startup.service. Your datacenter is now fully autonomous!