Last time we went through the basic mechanics of V2V. In this post we will roll up our virtual sleeves (lest we get ketchup on them… again) and start digging into what needs to happen to get this thing automated.
NOTE: You really want to back up your VM somehow before you start any conversion. You can do that using something as simple as a snapshot or using a backup tool like DPM. I’m not going to cover any of that. I’m just adding a reminder so you can’t say I didn’t mention it.
Preparing your VM by removing the VMware components
Now some people will ask: “Hey, doesn’t V2V already remove my VMware tools or something?”
The short answer is “No, with a ‘but’ ” and the long answer is “Yes, with an ‘if’ ”.
One of the biggest hassles with converting a VM from a VMware environment to Hyper-V is that the VMware tools can’t be run under Hyper-V. They will cause all manner of problems, usually culminating in a VM that won’t even boot. This isn’t exactly a secret though, so to combat this problem the developers added some code that would try and block some of these problems. V2V does have a mechanism that is designed to prevent certain things from starting.
Blocklist.xml
Our list of things to block is an XML file, which is curiously enough called the Blocklist.xml. This list is used to stop services and programs from starting when the machine boots on Hyper-V. This method works… sometimes.
I have converted VMs using V2V that had a running copy of VMware tools on them and this mechanism was able to prevent those bits from starting. This allowed Hyper-V to install Integration Components and get going properly. Of course even then I still had to uninstall the VMware tools manually.
On the other hand, I have seen VMware tools that slipped by and left me with a VM that wouldn’t boot. Leaving me back at square one. Good thing I backed everything up.
So I’m here to advocate not using the blocklist or to not rely on it (it’s sorta baked in so we can’t really escape it).
Why not use the blocklist? A few reasons:
- It isn’t supported.
- It isn’t documented.
- The list has not changed over time.
- You’re still left with VMware tools installed on your VM
- You’re told to remove VMware tools first anyway.
If you sniff around the documentation and the web you will see that the guidance is to remove your VMware tools before you start your V2V. Once the tools are gone, we don’t need to worry about that compatibility, so why not do that first and save the headache?
“Okay, Okay, I’ve convinced me”, you’re thinking, “so show me how to removes these things already”.
The funny thing about VMware tools, they are easy to install. Really easy. Easy to upgrade too. Multi-select, right click. Easy. But have a look around the vSphere client for the “Uninstall VMware Tools” option. Good luck with that. They don’t have any mechanism for uninstalling their tools. Who can’t blame them really? Why would you want to take away your ability to manage the VM?
Anyway, we can remove them, even if it’s a bit of work. Here’s how:
PowerCLI and tool removal
If you aren’t familiar with PowerCLI, it’s a set of PowerShell cmdlets from VMware that you can install on Windows. This lets you use PowerShell to script functions against VMware hosts or guest using functions that VMware provides.
You can download it here.
What we need to do is use PowerCLI to issue a command to the guest VM which instructs it to remove the VMware tools. Basically we are taking advantage of a nice management function to remove the management itself. In fact, once we succeed in doing so we will be left with a VM that can only be powered on or off.
The cmdlet we want to use is Invoke-VMScript which lets us execute a command directly within the guest. The command that we need to issue is going to depend on a few things.
- Is it a windows machine or a Linux machine
- What is the version/type of the OS
- What is the version of the VMware Tools
Windows client uninstall
The easiest way to uninstall the VMware tools from a Windows guest that I have found is using MSIEXEC (the command line for interacting with the Windows Installer). The actual command will look something like this:
MsiExec.exe /x {FE2F6A2C-196E-4210-9C04-2B1BC21F07EF} /qn /norestart & shutdown -s -t 120 -f
Hopefully this command is pretty easy to understand.
Uninstall (/x) the Product Code (GUID) without displaying a UI (/qn) and not requiring a restart (/norestart). Then we issue a shutdown command with the switches for shutdown and not reboot (-s) delayed by 2 mins (-t 120) and forcing open applications to close (-f).
There are two elements in italics are the reason I say “something like this”. You need to know what the GUID is for the version of the VMware tools you have installed and you might need to adjust the time you wait before shutting down.
The GUID
Before you can issue the command above you need to know what GUID your VM is using to refer to its VMware tools install. How to find this:
- Open regedit.
- Browse to HKLM \Software\Microsoft\Windows\CurrentVersion\uninstall.
- Search for the branch with a key named DisplayName and find the value “VMware Tools”.
- Record the name of the registry key (it will be a GUID like {FE2F6A2C-196E-4210-9C04-2B1BC21F07EF}
Odds are your organization is only using or two versions (likely a current and a down-level version) of the VMware tools. You can also check this using PowerCLI (see below). Make sure you have a complete list before you get going.
Putting it all together
Now that you have your GUID you can construct the script with PowerShell and PowerCLI. You need to replace the items in bold italic with your actual values
Add-PSSnapin "VMware.VimAutomation.Core"
Connect-VIServer (Your Vcenter or ESX Server)
$Script = "MsiExec.exe /x GUID /qn /norestart & shutdown -s -t 120 -f"
$RemoveTools = Invoke-VMScript -ScriptText $Script –vm Name -GuestUser GID -GuestPassword GPwd -HostUser HID -HostPassword HPwd -ScriptType "bat" -runasync
do {Start-Sleep -s 5} until($removetools.state -ne "Running")
Breaking down the above:
Load the snapin so you can use the Invoke-VMScript cmdlet
Connect to the server
Create a variable called $Script to hold the command
Run the Invoke-VMScript cmdlet using $Script and a bunch of other values for the Host and Guest (these need to be admin users on the targets)
Sleep in 5 second intervals until the cmdlet has finished.
You will want to experiment with the shutdown timer and the idea of introducing another delay to make sure the Power Off has fully completed before you move on. How fast your environment is will dictate that.
Linux client uninstall
Uninstalling the Linux client is a little more straightforward since Linux doesn’t install (or uninstall) things in the same way that Windows does. This time around we don’t need any GUID, we just need to know where the install files are. Turns out there’s a script file we can call – this pl will uninstall the client for us. You just need to find it.
Most of the time it is in /usr/bin/ and is called vmware-uninstall-tools.pl but you may also find it in other places if you customized the install.
Add-PSSnapin "VMware.VimAutomation.Core"
Connect-VIServer (Your Vcenter or ESX Server)
$Script = "/usr/bin/vmware-uninstall-tools.pl | shutdown -h +3"
$RemoveTools = Invoke-VMScript -ScriptText $Script –vm Name -GuestUser GID -GuestPassword GPwd -HostUser HID -HostPassword HPwd -ScriptType "BASH" -runasync
do {Start-Sleep -s 5} until($removetools.state -ne "Running")
So this looks pretty familiar. The script is calling the uninstall pl script and then piping this to a shutdown command. The effect is the same as the earlier Windows example.
The BIG difference is the –ScriptType is now “BASH” not “bat”. Subtle but important.
Like the Windows example, you may need to play with the shutdown timers and the idea of adding a delay after the command finishes.
Getting even more automate-y
So maybe you have a lot of versions of the VMware client installed. Maybe you just really hate clicking on UIs but love scripting. Migration Mark understands. He doesn’t judge.
I created a table that can help you find some of the most common GUIDs based on the version of VMware Tools and the type of OS. The following script will help you get what you need:
Add-PSSnapin "VMware.VimAutomation.Core"
$VM = "(Your VM Name)"
Connect-VIServer (Your Vcenter or ESX Server)
$VMView = Get-VM $VM | Get-View
$ToolsVersion = $VMView.guest.ToolsVersion
$GuestOSVersion = $VMView.guest.GuestID
$GuestOSFamily = $VMView.guest.GuestFamily
$ToolsVersion is the internal number VMware uses to uniquely identify the version of VMware tools. (Many Tools versions will have the same GUID, so if you notice this, it isn’t a misprint)
$GuestID is the internal name VMware gives to the operating systems. Not so easy to guess. It’s not Vista is winLonghornGuest – got it? Yeah, just use the command.
$GuestOSFamily is either Windows or Linux
Oh and $VM should be the Name you see in the VMware client UI, not necessarily the actual FQDN.
Once you have those three values you can run that against this table to get the resulting GUID
Tools Version | GUID | GuestOSVersion | GuestOSFamily |
8196 | {FE2F6A2C-196E-4210-9C04-2B1BC21F07EF} | winNetEnterpriseGuest | windowsGuest |
8198 | {FE2F6A2C-196E-4210-9C04-2B1BC21F07EF} | winNetEnterpriseGuest | windowsGuest |
8295 | {FE2F6A2C-196E-4210-9C04-2B1BC21F07EF} | winNetEnterpriseGuest | windowsGuest |
8384 | {A5CD39D8-F8A7-494F-9357-878A4AB6537F} | win7Server64Guest | windowsGuest |
8384 | {62198C42-974B-4F90-9AD2-12763AB58C97} | winNetEnterpriseGuest | windowsGuest |
8384 | {62198C42-974B-4F90-9AD2-12763AB58C97} | winLonghornGuest | windowsGuest |
8384 | {A5CD39D8-F8A7-494F-9357-878A4AB6537F} | winLonghorn64Guest | windowsGuest |
8384 | {A5CD39D8-F8A7-494F-9357-878A4AB6537F} | winNetEnterprise64Guest | windowsGuest |
8196 | {FE2F6A2C-196E-4210-9C04-2B1BC21F07EF} | win7Server64Guest | windowsGuest |
8196 | {FE2F6A2C-196E-4210-9C04-2B1BC21F07EF} | winLonghornGuest | windowsGuest |
8196 | {FE2F6A2C-196E-4210-9C04-2B1BC21F07EF} | winLonghorn64Guest | windowsGuest |
8196 | {FE2F6A2C-196E-4210-9C04-2B1BC21F07EF} | winNetEnterprise64Guest | windowsGuest |
8198 | {FE2F6A2C-196E-4210-9C04-2B1BC21F07EF} | win7Server64Guest | windowsGuest |
8198 | {FE2F6A2C-196E-4210-9C04-2B1BC21F07EF} | winLonghornGuest | windowsGuest |
8198 | {FE2F6A2C-196E-4210-9C04-2B1BC21F07EF} | winLonghorn64Guest | windowsGuest |
8198 | {FE2F6A2C-196E-4210-9C04-2B1BC21F07EF} | winNetEnterprise64Guest | windowsGuest |
8295 | {FE2F6A2C-196E-4210-9C04-2B1BC21F07EF} | winNetEnterprise64Guest | windowsGuest |
8295 | {FE2F6A2C-196E-4210-9C04-2B1BC21F07EF} | winLonghorn64Guest | windowsGuest |
8295 | {FE2F6A2C-196E-4210-9C04-2B1BC21F07EF} | winLonghornGuest | windowsGuest |
8295 | {FE2F6A2C-196E-4210-9C04-2B1BC21F07EF} | win7Server64Guest | windowsGuest |
8295 | {FE2F6A2C-196E-4210-9C04-2B1BC21F07EF} | windows7Server64Guest | windowsGuest |
8389 | {DD3770AA-8012-453F-AD8D-0B6D91ED40D5} | winNetEnterpriseGuest | windowsGuest |
8389 | {A2CC6F0B-E888-4485-82F5-587699B3CDB7} | winLonghorn64Guest | windowsGuest |
8384 | {A5CD39D8-F8A7-494F-9357-878A4AB6537F} | windows7Server64Guest | windowsGuest |
8384 | {62198C42-974B-4F90-9AD2-12763AB58C97} | windowsLonghornGuest | windowsGuest |
8384 | {A5CD39D8-F8A7-494F-9357-878A4AB6537F} | windowsLonghorn64Guest | windowsGuest |
8196 | {FE2F6A2C-196E-4210-9C04-2B1BC21F07EF} | windows7Server64Guest | windowsGuest |
8196 | {FE2F6A2C-196E-4210-9C04-2B1BC21F07EF} | windowsLonghornGuest | windowsGuest |
8196 | {FE2F6A2C-196E-4210-9C04-2B1BC21F07EF} | windowsLonghorn64Guest | windowsGuest |
8198 | {FE2F6A2C-196E-4210-9C04-2B1BC21F07EF} | windows7Server64Guest | windowsGuest |
8198 | {FE2F6A2C-196E-4210-9C04-2B1BC21F07EF} | windowsLonghornGuest | windowsGuest |
8198 | {FE2F6A2C-196E-4210-9C04-2B1BC21F07EF} | windowsLonghorn64Guest | windowsGuest |
8295 | {FE2F6A2C-196E-4210-9C04-2B1BC21F07EF} | windowsLonghorn64Guest | windowsGuest |
8295 | {FE2F6A2C-196E-4210-9C04-2B1BC21F07EF} | windowsLonghornGuest | windowsGuest |
8295 | {FE2F6A2C-196E-4210-9C04-2B1BC21F07EF} | windows7Server64Guest | windowsGuest |
8389 | {A2CC6F0B-E888-4485-82F5-587699B3CDB7} | windowsLonghorn64Guest | windowsGuest |
8295 | {FE2F6A2C-196E-4210-9C04-2B1BC21F07EF} | windows7Server64Guest | windowsGuest |
8384 | /usr/bin/vmware-uninstall-tools.pl | shutdown -h +3 | centos64Guest | linuxGuest |
8384 | /usr/bin/vmware-uninstall-tools.pl | shutdown -h +3 | redhatGuest | linuxGuest |
8384 | /usr/bin/vmware-uninstall-tools.pl | shutdown -h +3 | sles11_64Guest | linuxGuest |
8384 | /usr/bin/vmware-uninstall-tools.pl | shutdown -h +3 | centos64Guest | linuxGuest |
8384 | /usr/bin/vmware-uninstall-tools.pl | shutdown -h +3 | redhatGuest | linuxGuest |
8384 | /usr/bin/vmware-uninstall-tools.pl | shutdown -h +3 | sles11_64Guest | linuxGuest |
8295 | /usr/bin/vmware-uninstall-tools.pl | shutdown -h +3 | centos64Guest | linuxGuest |
8295 | /usr/bin/vmware-uninstall-tools.pl | shutdown -h +3 | rhel5_64Guest | linuxGuest |
8295 | /usr/bin/vmware-uninstall-tools.pl | shutdown -h +3 | sles10_64Guest | linuxGuest |
8295 | /usr/bin/vmware-uninstall-tools.pl | shutdown -h +3 | rhel6_64Guest | linuxGuest |
8295 | /usr/bin/vmware-uninstall-tools.pl | shutdown -h +3 | sles11_64Guest | linuxGuest |
Wow, you scrolled all the way down! You’re very diligent.
Next time: Getting the VM to the VMM Library