Every now and then I get asked how to detect whenever a virtual machine changes state. Usually, people who ask about this have written some code that periodically queries Hyper-V to see what state different virtual machines are in (stopped, running, etc.). What they find is that this is not efficient – and it sometimes misses a virtual machine that has quickly changed state (e.g. stopped and started again).
Luckily, there is a way to be notified of virtual machine state changes without polling for information.
To do this – you want to use WMI instance modification events:
# WMI Query that specifies what events we will watch for$Query = "Select * from __InstanceModificationEvent within 3 where TargetInstance ISA 'MSVM_ComputerSystem' `and TargetInstance.EnabledState <> PreviousInstance.EnabledState"
# Script block that will run whenever the event fires[ScriptBlock]$Action = {$VMName = $Event.SourceEventArgs.NewEvent.TargetInstance.ElementName
switch ($Event.SourceEventArgs.NewEvent.TargetInstance.EnabledState) { 2 {$vmState = "running"} 3 {$vmState = "turned off"} 9 {$vmState = "paused"} 6 {$vmState = "in a saved state"} 10 {$vmState = "starting"} 4 {$vmState = "stopping"}default {$vmState = "in an unknown state..."}
}
if ($Event.SourceEventArgs.NewEvent.TargetInstance.EnabledState -eq 1)
{$vmState = $Event.SourceEventArgs.NewEvent.TargetInstance.OtherEnabledState} write-host "The virtual machine '$($vmName)' is now $($vmState)."}# Register for the eventsRegister-WMIEvent -Query $Query -Action $Action -Namespace root\virtualization\v2
# To clean up - run "Get-EventSubscriber | Unregister-Event"This code will print out a message whenever a virtual machine changes state.
Cheers,
Ben






