Make a clone of VirtualBox Machine that doesn't cause Windows Re-Activation after installing Windows

Thankfully, I noticed something about all of my Virtual Machines that I hadn't prepared as those guides had outlined.

I ran VBoxManage showvminfo <uuid|name> and noticed that the UUID valued matched the Hardware UUID value, leading me to surmise that if any VM Definition didn't have a uuid attribute in the /VirtualBox/Machine/Hardware node, then the VM would use the "Machine UUID" value as the "Hardware UUID" value. So, for my template VM, it did have a "Hardware UUID" that I could use; I just had to find how to transfer it to any clones I would make.

To ensure that the UUID transfers, you can take one of two approaches:

  • You can edit the template VM Definition file directly. The "Hardware UUID" will only transfer to clones if the /VirtualBox/Machine/Hardware has the uuid attribute. So, copy the /VirtualBox/Machine uuid attribute and add it to the /VirtualBox/Machine/Hardware uuid attribute. You probably want to re-initialize the VirtualBox machine database after this, by closing/killing any VirtualBox process you're running. (VBoxSVC sometimes lingers on Windows; you may have to kill it from the Task Manager.)
  • You can clone your template and make a new template VM, and then use VBoxManage modifyvm <uuid|name> --hardwareuuid <uuid> to set the new template's "Hardware UUID" to the original template's "Machine UUID"/"Hardware UUID". I say you have to clone the VM to create a new template VM because if you try to set the "Hardware UUID" with this command on the original template, it won't add the uuid attribute to the /VirtualBox/Machine/Hardware node, since it can still imply it from the "Machine UUID", and thus won't copy this value to any clone it makes.

This powershell script does the work:

  1. clone the machine that is already activated.
  2. close virtualbox precesses from task manager.
  3. run this script, modifing the variables to your values.

Remember that the virtual machines names are case sensitive.

$ORIGVirtualMachineName="BaseDevWin7"
$clonedVirtualMachineName="DevWin7a"
$vboxDir="c:\Program Files\Oracle\VirtualBox"
cd $vboxDir
$uid=$($($(.\VBoxManage.exe showvminfo $ORIGVirtualMachineName|select-string "Hardware UUID:").ToString()).Split())[4]
.\VBoxManage modifyvm $clonedVirtualMachineName --hardwareuuid $uid

Thanks to the hints above I have successfully cloned a machine with Win7 guest running on a Kubuntu host for test purposes without re-activation.

My machine was activated already and (as described above) actually had no hardware UUID.

For me it looks like the MACHINE UUID is only for Virtualbox management, whereas the HARDWARE UUID is used by Windows activation logic. If there is no hardware UUID then Virtualbox provides the machine UUID to the guest, i.e. Microsoft knows the machine UUID.

So this is how it worked well without re-activation in my case: 1) Copy the virtual machine (folder) with normal file browser. 2) Open the .vbox file in a simple text editor. 3) As there was no UUID attribute for the "hardware", copy the machine UUID attribute (e.g. uuid="{xxx11111-2222-3333-4444-xxxxxxxxxxxx}" ) to the "hardware" entry. 4) Generate a new UUID for the machine, e.g. with uuidgenerator.net. 5) Overwrite the UUID machine VALUE with the generated UUID value. => Done.

In order to manage both machines in parallel in VB Manager it is more tricky:
1. Rename the clones's harddisk .vdi file.
2. In command line provide a new UUID to the harddisk via command "VBoxManage internalcommands sethduuid .vdi. VBManager will set a new UUID and display it.
3. In VB Manager add the new machine. Edit the machine by adding the new harddisk file (and remove original vdi, if still present).

Now you have unique IDs for all virtual machines and harddisks. You can manage both machine's within the VB Manager in parallel.