Quick and Dirty Reset of a Hyper-V VM with PowerShell

Note: Remember, this is a “Quick and Dirty” solution. In fact, because credentials are hard‐coded in the script, it is “Quick and Filthy”. But that tends to be the nature of IT‐Pro quick fixes, and I found it useful for a particular scenario. Just remember, this is merely being shown as an example and not a best practice.

Background: I had a problematic VM that would freeze over a period of time which required a “Hard Reset” to make it functional again. I wanted a way to reset the VM remotely, rather than from the console of the Hyper‐V parent.

The following steps will be taken to perform a hard reset on a VM:

  1. List ﴾enumerate﴿ the virtual machines on a Hyper‐V parent and identify the VM to reset by capturing its “Name” ﴾GUID﴿.
  2. Build a credential object that allows the execution of the RequestStateChange method ﴾typically Administrator credentials are required﴿.
  3. Execute the RequestStateChange method

List ﴾Enumerate﴿ the virtual machines on a Hyper‐V parent

PS> winrm enumerate wmi/root/virtualization/msvm_computersystem /r:<Hyper-V Parent> /u:<username> /p:<password>
     Msvm_ComputerSystem
     AssignedNumaNodeList = 0
     Caption = Virtual Machine
     CreationClassName = Msvm_ComputerSystem
     Description = Microsoft Virtual Machine
     ElementName = WSMANR2
     EnabledDefault = 2
     EnabledState = 2
     HealthState = 5
     InstallDate
     Datetime = 20110725T20:31:41Z
     Name = C4E916BB92D54A4097C10664FCC0123B
     NameFormat = null
     OnTimeInMilliseconds = 5774786
     OperationalStatus = 2
     OtherEnabledState = null
     PrimaryOwnerContact = null
     PrimaryOwnerName = null
     ProcessID = 2064
     RequestedState = 12
     ResetCapability = 1
     Status = null
     StatusDescriptions = Operating normally
     TimeOfLastConfigurationChange
          Datetime = 20110822T17:33:46.726979Z
     TimeOfLastStateChange
          Datetime = 20110822T17:33:46Z

Build a credential object ﴾this approach allows for the credentials to be hardcoded into a script, whereas the typical “get‐credential” cmdlet will not allow the password to be stored in the script and enforces the more secure method of manual entry of the password﴿.

PS> $password = convertto-securestring -String "<password>" -asplaintext -force
PS> $credential = new-object -typename System.Management.Automation.PSCredential -argumentlist "<username>",$password

Execute the RequestStateChange method on the VM ﴾acts like a Hard Reset for this example﴿

PS> # Various supported state changes: 2=Turns the VM on, 3=Turns the VM off, 10=A hard reset of the VM, 32768=Pauses the VM, 32769=Saves the state of the VM
PS> invoke-wsmanaction -action RequestStateChange -resourceuri wmi/root/virtualization/msvm_computersystem valueset @{RequestedState="10"} –selectorset @{Name="<VM Name/GUID from Above>"} -computername <HyperV Parent> -authentication default -credential $credential

Enjoy!

Hyper-V Virtual Identification

Since virtual machines can be easily moved between physical hosts (parents), it becomes important to track where virtual machines are physically residing for both asset management as well as troubleshooting purposes. The following post focuses on discovering the relationship between virtual hosts (parents) and the virtual machines (children) from both the perspective of the parent as well as the perspective of the child.

HyperV-ID-1

Note: The following examples use the WinRM and WinRS command-line utilities which shipped with Windows Vista and Windows Server 2008, but are also available as an Out-Of-Band install for Windows XP SP2+ and Windows Server 2003 SP1+ here.

Query the Parent:

Most commonly used for asset collection, this model gathers the names (and other virtual machine characteristics) of all the children running on a virtual host. This method queries the Hyper-V specific WMI provider/class by using the following command.

winrm enumerate wmi/root/virtualization/msvm_computersystem /r:<remote Hyper-V Host>

With the following sample output:

Msvm_ComputerSystem
     AssignedNumaNodeList = 0
     Caption = Virtual Machine
     CreationClassName = Msvm_ComputerSystem
     Description = Microsoft Virtual Machine
     ElementName = PROV-XP
     EnabledDefault = 2
     EnabledState = 2
     HealthState = 5
     InstallDate
          Datetime = 2008-07-01T21:47:02Z
     Name = 31F497F1-2437-4E89-8308-BE07FB5C14C2
     NameFormat = null
     OnTimeInMilliseconds = 432464839
     OperationalStatus = 2
     OtherEnabledState = null
     PrimaryOwnerContact = null
     PrimaryOwnerName = OTTOH-HOST\Administrator
     ProcessID = 2628
     RequestedState = 12
     ResetCapability = 1
     Status = null
     TimeOfLastConfigurationChange
          Datetime = 2008-07-30T17:07:06Z
     TimeOfLastStateChange
          Datetime = 2008-07-30T17:07:06Z

Query the Child:

Most commonly used for troubleshooting scenarios where a virtual machine is being evaluated and needs to be queried in order to determine its physical host (parent). The following command queries the registry on the child in order to determine its host (parent):

HyperV-ID-2

Remote Access Method #1 (the /f parameter merely structures the output in XML – handy for scripting, especially in PowerShell):

winrm invoke GetStringValue wmi/root/default/StdRegProv @{hDefKey="2147483650";sSubKeyName="Software\Microsoft\Virtual Machine\Guest\Parameters";sValueName="PhysicalHostNameFullyQualified"} /r:<Remote VM> /u:<Username> /p:<Password> /f:pretty

Remote Access Method #2:

winrs /r:<Remote VM> /u:<Username> /p:<Password> reg query "HKLM\Software\Microsoft\Virtual Machine\Guest\Parameters" /v PhysicalHostNameFullyQualified

Note: The first method demonstrates a powerful way to access the value of any registry key using the ‘StdRegProv’ WMI provider via WS-Man/WinRM for remote transport. Other registry hives can be accessed with the following hDefKey values: HKLM=2147483650, HKCU=2147483649, HKCR=2147483648, HKEY_USERS=2147483651.

Enjoy!