Automatically hibernate Azure VMs when idle, using IMDS + Managed Identity.
Runs as a lightweight Windows service with optional toast notifications.
Grab the latest binaries here:
https://github.com/smitstech/AzureAutoHibernate/releases
- Idle detection with configurable thresholds
- Pre-hibernate toast notification
- Hibernate via Azure IMDS using Managed Identity
- Windows service + notifier app
- No Azure credentials stored locally
- Extremely lightweight and safe
Dev/test VMs cost money when left running.
AzureAutoHibernate shuts them down automatically when they're idle — similar to a laptop closing the lid.
az vm identity assign --name YOUR_VM --resource-group YOUR_RGPRINCIPAL_ID=$(az vm identity show --name YOUR_VM --resource-group YOUR_RG --query principalId -o tsv)
az role assignment create \
--assignee $PRINCIPAL_ID \
--role "Virtual Machine Contributor" \
--scope "/subscriptions/YOUR_SUBSCRIPTION/resourceGroups/YOUR_RG/providers/Microsoft.Compute/virtualMachines/YOUR_VM"Place these in a folder (e.g., C:\Program Files\AzureAutoHibernate\):
AzureAutoHibernate.exeAzureAutoHibernate.Notifier.exeAzureAutoHibernate.Updater.execonfig.json
AzureAutoHibernate.exe -install
sc create AzureAutoHibernate binPath= "C:\Program Files\AzureAutoHibernate\AzureAutoHibernate.exe" start= auto
sc start AzureAutoHibernateOpen Event Viewer → Applications and Services Logs → AzureAutoHibernate
-
Automatic VM Discovery via Azure IMDS
-
Session Monitoring for active + disconnected users
-
Keyboard/Mouse Activity Detection
-
Three Idle Conditions (configurable thresholds):
- No users logged in
- All users disconnected
- Logged-in user inactive
-
User Warnings via toast notifications
- Configurable warning period
- Shows time remaining + hibernation reason
- Cancellable via user activity
-
Minimum Uptime Enforcement (prevents boot→hibernate loops)
-
Azure Integration (hibernate via Managed Identity)
-
Windows Service with auto-startup
-
Dynamic Polling for minimal overhead
-
Event Log Integration with categorized event IDs
-
Flexible Logging (
debug,info,warn,error) -
Auto-Update (optional, checks GitHub releases)
- Windows VM running on Azure
- VM size must support Hibernate
- System Managed Identity enabled
- Managed Identity must have the hibernate action permission
- Go 1.21+ (only required if building from source)
Example config.json:
{
"noUsersIdleMinutes": 15,
"allDisconnectedIdleMinutes": 15,
"inactiveUserIdleMinutes": 30,
"inactiveUserWarningMinutes": 5,
"minimumUptimeMinutes": 5,
"logLevel": "info",
"autoUpdate": false,
"updateCheckIntervalHr": 24
}| Parameter | Description | Default |
|---|---|---|
noUsersIdleMinutes |
Hibernate when no users logged in | 15 |
allDisconnectedIdleMinutes |
Hibernate when all sessions disconnected | 15 |
inactiveUserIdleMinutes |
Hibernate when no input detected | 30 |
inactiveUserWarningMinutes |
Warning countdown before hibernate | 5 |
minimumUptimeMinutes |
Minimum uptime after boot/resume | 5 |
logLevel |
Logging verbosity | info |
autoUpdate |
Enable automatic update checking | false |
updateCheckIntervalHr |
Hours between update checks | 24 |
Notes:
- At least one idle condition must be > 0
- Warning period applies only to inactive-user condition
- Auto-update downloads from GitHub releases and restarts the service automatically
On Windows (PowerShell):
.\build.ps1On Linux/Mac (with Make):
make buildBoth methods automatically inject version information from git tags.
AzureAutoHibernate.exe -versionOutput:
v1.0.0
To build manually without version injection:
On Windows:
go build -o AzureAutoHibernate.exe ./cmd/autohibernate
go build -ldflags="-H=windowsgui" -o AzureAutoHibernate.Notifier.exe ./cmd/notifierTo cross-compile from Linux/Mac:
GOOS=windows GOARCH=amd64 go build -o AzureAutoHibernate.exe ./cmd/autohibernate
GOOS=windows GOARCH=amd64 go build -ldflags="-H=windowsgui" -o AzureAutoHibernate.Notifier.exe ./cmd/notifierExecutables:
AzureAutoHibernate.exe— the SYSTEM Windows serviceAzureAutoHibernate.Notifier.exe— per-session notifier UIAzureAutoHibernate.Updater.exe— update helper (applies updates after service stops)
AzureAutoHibernate.exe -debuggo test ./...Event Viewer → AzureAutoHibernate
AzureAutoHibernate.exe -check-updateThis will check GitHub releases and report if a newer version is available.
Set autoUpdate: true in config.json to enable automatic updates. The service will:
- Check for updates at the configured interval (default: every 24 hours)
- Download new versions from GitHub releases
- Spawn the updater helper process
- Updater stops the service reliably (with retries and 10-minute timeout)
- Replace executable files (config.json is merged, not replaced)
- Restart the service automatically
Safe & Reliable:
- User settings preserved: Your
config.jsonpreferences are kept, new fields added automatically - Fails safely: Update won't proceed if service won't stop (prevents broken updates)
- Progress logging: Updates logged to
%TEMP%\AzureAutoHibernate.Updater.log - Version verification: Check Windows Event Log after restart to confirm version
Note: The updater process runs with the same permissions as the service (SYSTEM).
- Loads configuration
- Retrieves VM metadata via IMDS
- Validates Managed Identity and capabilities
- Polls infrequently when far from thresholds
- Polls every 5 seconds during warning windows
- No Users → Immediate hibernate
- All Disconnected → Immediate hibernate
- Inactive User → Warning period → Hibernate
- Notifier displays toast notifications
- User movement cancels countdown instantly
- Notifications throttled to once every 30 seconds
- Gets token from IMDS
- Calls Azure Hibernate API
- VM hibernates preserving memory to disk
AzureAutoHibernate.exe (SYSTEM)
├─ IdleMonitor
├─ NotifierManager
│ └─ AzureAutoHibernate.Notifier.exe (per session)
├─ AzureHibernateClient
└─ UpdateChecker (optional)
└─ AzureAutoHibernate.Updater.exe (on update)
Service (SYSTEM) → Named Pipe (JSON) → AzureAutoHibernate.Notifier.exe (User Session)
Session-0 isolation requires this two-process design.
- Make sure Windows Notifications are enabled
- Ensure
AzureAutoHibernate.Notifier.exeis present - Confirm service runs as SYSTEM
- Check Event Log for
ERROR_NOT_ALL_ASSIGNED
- Confirm Azure Hibernate is enabled for VM size
- Check Managed Identity permissions
- Look for Azure API errors in Event Log
- IMDS blocked or unreachable
- VM not running in Azure
- Runs as LocalSystem to access session info
- Uses Managed Identity, no secrets stored
- Metadata retrieved at runtime via IMDS
- Access tokens never persisted
- Automatically exits if not running on Azure
See CONTRIBUTING.md
MIT