Using Scripting API for Advanced Operations in Windows Virtual PC

Windows® Virtual PC (WVPC) brings for the first time scriptable API to a Microsoft client virtualization product. These APIs are a very powerful tool in the hands of power users and administrator to do some very cool things and achieve functionality which is not obvious or possible from the normal user interface. We present here a few examples of how to use these API in Windows PowerShell®.

Deleting a Virtual Machine completely

Windows virtual PC provides a new and unique console view for Virtual Machine (VM) management. Here, VMs are represented as files ( .vmcx) in the Virtual Machines folder. The Virtual Machines folder is present at ( %systemdrive%\Users\<user name>\Virtual Machines). Here you can see how many VMs are registered on your system, their state and create new VMs. Removing a VM is just deleting the .vmcx file. But this does not remove the VM completely. Rather, it just unregisters the VM, and the virtual machine files are still present on your system (in the folder %localappdata%\Microsoft\Windows Virtual PC\Virtual Machines\ ) which you can bring back very easily by just double-clicking on the .vmc file. But this would create a lot of clutter on your system over time if you create a lot of VMs.

Using the following PowerShell script you can easily remove a VM completely. Please replace “My VM” with the name of your virtual machine. Be very careful while using this script as it would remove all the files related to your virtual machine including VHDs.

    1: $vpc = New-Object -ComObject "virtualpc.application"
    2:  
    3: $vm = $vpc.FindVirtualMachine("My VM")
    4:  
    5: if ( $vm )
    6:  
    7: {
    8:  
    9: if ($vm.state -eq 5) # check for running state
   10:  
   11: {
   12:  
   13: echo "cannot delete a running VM"
   14:  
   15: }
   16:  
   17: else 
   18:  
   19: {
   20:  
   21: if ($vm.state -eq 2) # check for saved state
   22:  
   23: {
   24:  
   25: echo "Discarding saved state"
   26:  
   27: $vm.DiscardSavedState()
   28:  
   29: }
   30:  
   31: if ($vm.undoable -eq $true)
   32:  
   33: {
   34:  
   35: echo "discarding undo disks"
   36:  
   37: $vm.DiscardUndoDisks()
   38:  
   39: }
   40:  
   41: foreach ($hdc in $vm.HardDiskConnections)
   42:  
   43: {
   44:  
   45: echo "deleting vhd file"
   46:  
   47: $hd = $hdc.HardDisk ;
   48:  
   49: $vm.RemoveHardDiskConnection($hdc) ;
   50:  
   51: del $hd.File ;
   52:  
   53: }
   54:  
   55: echo "deleting virtual machine"
   56:  
   57: $vpc.DeleteVirtualMachine($vm)
   58:  
   59: }
   60:  
   61: }
   62:  
   63: else
   64:  
   65: {
   66:  
   67: echo "VM does not exists"
   68:  
   69: }

Moving the parent of a VM’s hard disk to some other location

Moving a VM is easy. Just copy all the virtual machine files (.vmc, .vhd, .vsv etc) to a different location and double-click on the .vmc file to start the VM from there. What if your virtual machine has a differencing disk? If the parent VHD is located in the same folder as the child then you just need to move all the files together for relocating you VM. But if your VM’s parent is in some other folder, then you cannot change the location of the parent, otherwise your VHD chain would break and you would not be able to start your VM. Let us see, with the help of an example, how you can use the VPC COM APIs to get over this limitation.

Suppose the parent disk (parent.vhd) is present at c:\vhdstore.

Your other VM files are present in the usual location ( %localappdata%\Microsoft\Windows Virtual PC\Virtual Machines\ ) and you want to move these files to the D: drive as you want to format your C: drive. You place the parent VHD in the location D:\VHDStore and all the other files at D:\VMs. Now your VM won’t start as you parent location would not match with the one that is present in the child VHD.

Run the following commands on the PowerShell to restore the new path of the parent VHD and make the VM operational again. It’s assumed that your VM name is “My VM” and the new parent location is “D:\VHDStore\parent.vhd”

    1: $vpc = New-Object -ComObject "virtualpc.application"
    2:  
    3: $vm = $vpc.FindVirtualMachine("My VM")
    4:  
    5: $hd = $vpc.GetHardDisk("D:\VHDStore\parent.vhd")
    6:  
    7: $vm.HardDiskConnections.Item(1).harddisk.parent = $hd

Now you should be able to start your VM from the new location.

You can use this trick even if you just want to change the location of your parent VHD and not move the other files.

Disabling Time Sync between the host and guest

Windows virtual PC periodically syncs the time of the guest to that of the host to keep both of them in sync. But if you do not want that to happen then you can disable time sync totally using the following script. Please remember that the Virtual Machine should be in the turned off state before running this script.

    1: $vpc = New-Object -ComObject "virtualpc.application"
    2:  
    3: $vm = $vpc.FindVirtualMachine("My VM")
    4:  
    5: $vm.SetConfigurationValue("hardware/bios/time_sync_at_boot",$false)
    6:  
    7: $guest = $vm.GuestOS
    8:  
    9: $guest.IsHostTimeSyncEnabled = $false

In closing…

Using the COM APIs provided with WVPC, you can achieve some of the things that seem to be not possible using the conventional user interface.  Keep a watch on this blog space for more such tips and tricks. And you can check out the WVPC COM APIs here https://msdn.microsoft.com/en-us/library/dd796756(VS.85).aspx, and see the vast set of APIs provided to help with your VM management tasks.

Technorati Tags: Windows 7,Windows Virtual PC,Windows XP Mode,VPC,VHD,VM,Virtual Machine,Virtualization,VM scripts,Time Sync,Move VHD,Delete VM

Palash Kar

SDE

Microsoft Virtualization Team