none
Script to Save State on all Runnign Hyper-V VMs?

    Question

  • Need a script to save state on all the VMs running on a server with the Hyper-V role?
    Tony Soper
    Thursday, October 30, 2008 6:57 PM

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.ElementName

      RequestReturn = 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
    • Marked as answer by tonyso Thursday, October 30, 2008 6:59 PM
    • Edited by tonyso Thursday, October 30, 2008 6:59 PM
    Thursday, October 30, 2008 6:59 PM

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.ElementName

      RequestReturn = 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
    • Marked as answer by tonyso Thursday, October 30, 2008 6:59 PM
    • Edited by tonyso Thursday, October 30, 2008 6:59 PM
    Thursday, October 30, 2008 6:59 PM
  • hi,

    in my case this script doesn't work. I think the reason is, the HOST-Name is in vmcollection too..

    greetings
    bsd01
    Thursday, November 27, 2008 3:39 PM
  • 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
    Saturday, June 20, 2009 7:59 AM
  • Hi,

    I'm using the script above to start my virtual machines but I can't seem to get my code to gracefully shutdown the VM environment. I can shutdown these environments using the Hyper-V admin panel.

    I have not been able to find your list of codes anywhere! Thanks for the info but I think I am trying StateID 4 which is to show shuttingdown instead of shutdown. Not sure but Case 3 will turn it off.

    Below is my code: Can anyone help me shutdown my VM gracefully?

    Best Regards,

    Jason Nixon

     

    ##############################################################

    #Store Server names into an array

    ##############################################################

     

    $operation  = "shutdown"

    $servername = @("JNADEV")

    #, "PER-DUYGU-01", "PER-HASAN-01", "PER-OZAN-01", "PER-OZLEM-01", "PER-TOLGA-01")

     

    ForEach ($machine in $servername)

     

    {

    #Getting initial VM session names

      $Vm = Get-WmiObject -Namespace root\virtualization  -Query "Select * From Msvm_ComputerSystem Where ElementName = '$machine'"

      $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 $machine)

      {

        write-warning "Virtual machine does not exist!"

        break

      }

     

      if ($operation -eq 'shutdown')

      {

        $state = "shutdown"

        $stateId = 4

      }

     

    #Check if specified command is valid

      else

      { 

        write-warning "Unknown command."

        "Syntax: .\hvcmd2.ps1 [operation] [machine]"

        "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 = '$machine'"

     

     

    #Set the state

      $status = $Core.RequestStateChange($stateId)

     

    }

    Sunday, May 1, 2011 11:52 PM