Script to Save State on all Runnign Hyper-V VMs?
- Need a script to save state on all the VMs running on a server with the Hyper-V role?
Tony Soper
Answers
' Script that saves the state of running VMs on a Hyper-V enabled server
' Cobbled together by Johnkel@Microsoft.com
'
strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\virtualization")
Set vmcollecion = objWMIService.ExecQuery("SELECT * FROM Msvm_ComputerSystem",,48)Wscript.Echo VbCrLF
Wscript.Echo "Name Description State "
Wscript.Echo "--------------------------------------- ---------------------------------- -------------"' loop through all instances in collection
For each vm in vmcollecion
' decode system state, based on codes identified via trial and error
VMStateCode = vm.EnabledState
Select Case VMStateCode
Case 2 VMState = "Running"
Case 3 VMState = "PowerOff"
Case 4 VMState = "ShuttingDown"
Case 10 VMState = "Reset"
Case 32768 VMState = "Paused"
Case 32770 VMState = "Starting"
Case 32771 VMState = "SnapshotInProgress"
Case 32772 VMState = "Migrating"
Case 32773 VMState = "Saving"
Case 32774 VMState = "Stopping"
Case 32776 VMState = "Pausing"
Case 32777 VMState = "Resuming"
Case 32769 VMState = "Saved"
Case Else VMState = "Unclassified (so far)"
End Select' print out VM info state
Wscript.Echo VbCrLF
Wscript.Echo vm.ElementName & Space(40 - Len(vm.ElementName)) & _
vm.Description & Space(35 - Len(vm.Description)) & _
VMState & " (" & VMStateCode & ")"' request state change if appropriate - the host should never be eligible
if ( VMState = "Running" or VMState = "Paused") and vm.Description <> "Microsoft Hosting Computer System" Then
Wscript.Echo Space(40) & "Saving " & vm.ElementNameRequestReturn = vm.RequestStateChange(32769)
if RequestReturn = 4096 Then
Wscript.Echo Space(40) & "Save request submitted"
Else
Wscript.Echo Space(40) & "Something goofy happened (" & RequestReturn & ")"
End If
End If
Next
Wscript.Echo VbCrLF
Tony Soper
All Replies
' Script that saves the state of running VMs on a Hyper-V enabled server
' Cobbled together by Johnkel@Microsoft.com
'
strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\virtualization")
Set vmcollecion = objWMIService.ExecQuery("SELECT * FROM Msvm_ComputerSystem",,48)Wscript.Echo VbCrLF
Wscript.Echo "Name Description State "
Wscript.Echo "--------------------------------------- ---------------------------------- -------------"' loop through all instances in collection
For each vm in vmcollecion
' decode system state, based on codes identified via trial and error
VMStateCode = vm.EnabledState
Select Case VMStateCode
Case 2 VMState = "Running"
Case 3 VMState = "PowerOff"
Case 4 VMState = "ShuttingDown"
Case 10 VMState = "Reset"
Case 32768 VMState = "Paused"
Case 32770 VMState = "Starting"
Case 32771 VMState = "SnapshotInProgress"
Case 32772 VMState = "Migrating"
Case 32773 VMState = "Saving"
Case 32774 VMState = "Stopping"
Case 32776 VMState = "Pausing"
Case 32777 VMState = "Resuming"
Case 32769 VMState = "Saved"
Case Else VMState = "Unclassified (so far)"
End Select' print out VM info state
Wscript.Echo VbCrLF
Wscript.Echo vm.ElementName & Space(40 - Len(vm.ElementName)) & _
vm.Description & Space(35 - Len(vm.Description)) & _
VMState & " (" & VMStateCode & ")"' request state change if appropriate - the host should never be eligible
if ( VMState = "Running" or VMState = "Paused") and vm.Description <> "Microsoft Hosting Computer System" Then
Wscript.Echo Space(40) & "Saving " & vm.ElementNameRequestReturn = vm.RequestStateChange(32769)
if RequestReturn = 4096 Then
Wscript.Echo Space(40) & "Save request submitted"
Else
Wscript.Echo Space(40) & "Something goofy happened (" & RequestReturn & ")"
End If
End If
Next
Wscript.Echo VbCrLF
Tony Soper- hi,
in my case this script doesn't work. I think the reason is, the HOST-Name is in vmcollection too..
greetings
bsd01 - Aloha,
since i searched a long time for a working script to do different state-changes to a virtual machine, i wrote a powershell-script that does most of the needed things. Maybe it helps - even if this topic is old.
Updated versions can be found at http://capilla.codeplex.com/
# Daniel Capilla (anyWARE AG Mainz)
# Date: 2009-06-19
# Version 0.7
# - Initial stable beta
# Version 0.7.1
# - stable release
# - added error handling and output
# - restructuring script
# Updated versions can be found at http://capilla.codeplex.com/
# Syntax: .\hvcmd.ps1 [start|stop|pause|save|stop|shutdown|snapshot] [machinename]
#
# If you would like to start the script via task, use this commandline for example:
# powershell d:\hvcmd.ps1 "pause srv01"
#Getting Parameters from commandline
Param($operation, $servername)
#Getting initial VM session names
$Vm = Get-WmiObject -Namespace root\virtualization -Query "Select * From Msvm_ComputerSystem Where ElementName = '$servername'"
$VM_Service = get-wmiobject -namespace root\virtualization Msvm_VirtualSystemManagementService
$ListofVMs = get-wmiobject -namespace root\virtualization Msvm_ComputerSystem -filter “ElementName <> Name ”
#If there is no machine with the desired name, display a warning message
if ($VM.ElementName -ne $servername)
{
write-warning "Virtual machine does not exist!"
break
}
#Setting the "state" for later actions
if ($operation -eq 'start')
{
$state = "started"
$stateId = 2
}
elseif ($operation -eq 'stop')
{
$state = "stoped"
$stateId = 3
}
elseif ($operation -eq 'pause')
{
$state = "paused"
$stateId = 32768
}
elseif ($operation -eq 'save')
{
$state = "saved"
$stateId = 32769
}
elseif (($operation -eq 'shutdown') -and ($servername -ne $NUL))
{
#$VM_Service = get-wmiobject -namespace root\virtualization Msvm_VirtualSystemManagementService
$ListofVMs = get-wmiobject -namespace root\virtualization Msvm_ComputerSystem -filter “ElementName <> Name ”
$Vm = Get-WmiObject -Namespace root\virtualization -Query "Select * From Msvm_ComputerSystem Where ElementName = '$servername'"
$ShutdownIC = Get-WmiObject -Namespace root\virtualization -Query "Associators of {$Vm} Where AssocClass=Msvm_SystemDevice ResultClass=Msvm_ShutdownComponent"
$ShutdownIC.InitiateShutdown("TRUE", "Automated shutdown via script")
$state = "shutdown initiated"
#Do this break because of avoiding errors - not fine but working
break
}
elseif (($operation -eq 'snapshot') -and ($servername -ne $NUL))
{
#This part took a long time to get it to work, since the state "snapshot" is not recognized, or
#let's say - wrong recognized in some cases - the state-id "32771" did not work properly for us
#$VM_Service = get-wmiobject -namespace root\virtualization Msvm_VirtualSystemManagementService
#$ListofVMs = get-wmiobject -namespace root\virtualization Msvm_ComputerSystem -filter “ElementName <> Name ”
foreach ($VM in [array] $ListOfVMs)
{
# $VM.ElementName
# $VM.__PATH
IF ($VM.ElementName -eq $servername)
{
$VM_service.CreateVirtualSystemSnapShot($VM.__PATH)
$state = "snapshot initiated"
$stateId = (32771)
}
}
$servername + " " + $state
break
}
#Check if specified command is valid
else
{
write-warning "Unknown command."
"Syntax: .\hvcmd.ps1 [command] [machinename]"
"Commands: start stop pause save stop shutdown snapshot"
"Machinename: Name of the Virtual instance (for example: server01)"
break
}
#Get a handle to the VM object
$Core = get-wmiobject -namespace root\virtualization -class Msvm_Computersystem -filter "ElementName = '$servername'"
#Set the state
$status = $Core.RequestStateChange($stateId)
#Actual state
if ($status.ReturnValue -ne 32775)
{
$servername + " " + $state
}
elseif ($status.ReturnValue -eq 32775)
{
"Nothing changed - allready in this state."
}
Regards
Daniel Capilla

