# hyperv-vm-heartbeat.ps1 — per-VM heartbeat + state on a Hyper-V host. # Requires the Hyper-V module (RSAT-Hyper-V-Tools or the role installed). $Url = "YOUR_URL/hyperv" try { $VMs = Get-VM -ErrorAction Stop } catch { $Body = (@{ hostname = $env:COMPUTERNAME; error = "$($_.Exception.Message)" }) | ConvertTo-Json -Compress Invoke-RestMethod -Uri $Url -Method Post -Body $Body -ContentType "application/json" -TimeoutSec 15 | Out-Null exit 1 } $Stats = @{} $AnyUnhealthy = $false foreach ($vm in $VMs) { $hb = "$($vm.Heartbeat)" $state = "$($vm.State)" # 'OkApplicationsHealthy' or 'OkApplicationsUnknown' both count as healthy; # 'NoContact' / 'LostCommunication' / null mean the guest agent is silent. $healthy = ($state -eq 'Running' -and $hb -match '^Ok') $Stats[$vm.Name] = @{ state = $state heartbeat = $hb uptime_seconds = if ($vm.Uptime) { [int]$vm.Uptime.TotalSeconds } else { 0 } healthy = $healthy } if (-not $healthy -and $state -eq 'Running') { $AnyUnhealthy = $true } } $Body = (@{ hostname = $env:COMPUTERNAME vm_count = $VMs.Count vms = $Stats any_unhealthy = $AnyUnhealthy }) | ConvertTo-Json -Compress -Depth 5 Invoke-RestMethod -Uri $Url -Method Post -Body $Body ` -ContentType "application/json" -TimeoutSec 15 | Out-Null