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:
- List (enumerate) the virtual machines on a Hyper-V parent and identify the VM to reset by capturing its “Name” (GUID).
- Build a credential object that allows the execution of the RequestStateChange method (typically Administrator credentials are required).
- 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!