Renaming a Hyper-V Virtual Machine

Moving on we come to a sample script for changing a setting on a virtual machine - in this case I am changing the virtual machines name.

VBScript:

 Option Explicit
  
 Dim WMIService
 Dim VM
 Dim VMManagementService
 Dim VMSystemSettingData
 Dim VMName
 Dim NewVMName
 Dim Result
  
 'Setup variables for the VM we are looking for, and the new name
 VMName = "Windows Server 2003"
 NewVMName = "Windows Server 2003 - new"
  
 'Get an instance of the WMI Service in the virtualization namespace.
 Set WMIService = GetObject("winmgmts:\\.\root\virtualization")
  
 'Get a VMManagementService object
 Set VMManagementService = WMIService.ExecQuery("SELECT * FROM Msvm_VirtualSystemManagementService").ItemIndex(0)
  
 'Get the VM object that we want to modify
 Set VM = (WMIService.ExecQuery("SELECT * FROM Msvm_ComputerSystem WHERE ElementName='" & VMName & "'")).ItemIndex(0)
  
 'Get the VirtualSystemSettingsData of the VM we want to modify
 Set VMSystemSettingData = (VM.Associators_("MSVM_SettingsDefineState", "MSVM_VirtualSystemSettingData")).ItemIndex(0) 
  
 'Change the ElementName property
 VMSystemSettingData.ElementName = NewVMName
  
 'Update the VM with ModifyVirtualSystem
 Result = VMManagementService.ModifyVirtualSystem(VM.Path_.Path, VMSystemSettingData.GetText_(1))

PowerShell:

 #Setup variables for the VM we are looking for, and the new name
 $VMName = "Windows Server 2003"
 $NewVMName = "Windows Server 2003 - new"
  
 #Get a VMManagementService object
 $VMManagementService = gwmi -class "Msvm_VirtualSystemManagementService" -namespace "root\virtualization" -computername "."
  
 #Get the VM object that we want to modify
 $query = "SELECT * FROM Msvm_ComputerSystem WHERE ElementName='" + $VMName + "'"
 $VM = gwmi -query $query -namespace "root\virtualization" -computername "."
  
 #Get the VirtualSystemSettingsData of the VM we want to modify
 $query = "Associators of {$VM} WHERE AssocClass=MSVM_SettingsDefineState"
 $VMSystemSettingData = gwmi -query $query -namespace "root\virtualization" -computername "."
  
 #Change the ElementName property
 $VMSystemSettingData.ElementName = $NewVMName
  
 #Update the VM with ModifyVirtualSystem
 $Result = $VMManagementService.ModifyVirtualSystem($VM.__PATH,$VMSystemSettingData.psbase.GetText(1))

To change a setting on a virtual machine you do not just get the virtual machine object and change the property there.  What you need to do is to:

  1. Get the MSVM_VirtualSystemSettingData associated with the virtual machine (there is only one associated with each virtual machine).
  2. Modify the setting you want to change on the MSVM_VirtualSystemSettingData object.
  3. Get an instance MSVM_VirtualSystemManagementService.
  4. Call the ModifyVirtualSystem method on the MSVM_VirtualSystemManagementService and pass it the path of the virtual machine object and text serialization of the modified MSVM_VirtualSystemSettingData object.

As you can see this is a bit counter-intuitive but once you get your head around it, it is fairly easy to do.

Cheers,

Ben