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.

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 http://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.

You guys have just lost it when it comes to virtualization. One of the best uses of Virtual PC in the past is to virtualize a server environment so that you can demostrate a client/server application. Now it seems that you want to kill the installed base of Virtual PC users. To that, I say thank you for the nice memories, but it is time that I moved to a product with more of a life span that Virtual PC has.

I am trying to find a way to manage the VPC environment so that users cannot create, remove or modify the VMs. I need VPC to be installed because I use MEDV v2, but I do not want to give any right to users to manage VPC.

I have seen there are many possiblities to tailor VM settings wihing VPC but I did not see any way to achieve my aim.