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 = 2011-07-25T20:31:41Z
    Name = C4E916BB-92D5-4A40-97C1-0664FCC0123B
    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 = 2011-08-22T17:33:46.726979Z
    TimeOfLastStateChange
        Datetime = 2011-08-22T17: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 <Hyper-V Parent> -authentication default -credential $credential

That's it!