Automating VMWare to Hyper-V Migrations using MVMC

There are several tools for migrating VMWare VM’s to Hyper-V. The free tool from Microsoft is called the Microsoft Virtual Machine Converter which allows you to convert from VMWare to Hyper-V or Azure, and from physical to virtual via a GUI or powershell cmdlets for automation. Microsoft also has the Migration Automation Toolkit which can help automate this process. If you have NetApp, definitely check out MAT4SHIFT which is by far the fastest and easiest method for converting VMWare VM’s to Hyper-V. MVMC works fairly well, however, there are a few things the tool doesn’t handle natively when converting from VMWare to Hyper-V.

First, it requires credentials to the guest VM to remove the VMWare Tools. In a service provider environment, you may not have access to the guest OS, so this could be an issue. Second, the migration will inherently cause a change in hardware, which in turn can cause the guest OS to lose its network configuration. This script accounts for that by pulling the network configuration from the guest registry and restoring it after the migration. Lastly, MVMC may slightly alter other hardware specifications (dynamic memory, mac address) and this script aims to keep them as close as possible with the exception of disk configuration due to Gen 1 limitations in Hyper-V booting.

This script relies on several 3rd party components:

You’ll need to install MVMC, HV PS Module, and VMWare PowerCLI on your “helper” server – the server where you’ll be running this script which will perform the conversion. Devcon, the HV IS components, VMWare Tools, and NSSM will need to be extracted into the appropriate folders:

vmware-to-hyper-v-folder-structure

I’ve included a sample kick-off script (migrate.ps1) that will perform a migration:

$esxhost = "192.168.0.10"
$username = "root"
$password = ConvertTo-SecureString "p@ssWord1" -AsPlainText -Force
$cred = New-Object -Typename System.Management.Automation.PSCredential -Argumentlist "root", $password
$viserver = @{Server=$esxhost;Credential=$cred}
 
$destloc = "\\sofs.contoso.int\vm-storage1"
 
$vmhost = "HV03"
 
$vmname = "MYSERVER01"
 
cd C:\vmware-to-hyperv-convert
 
. .\vmware-to-hyperv.ps1 -viserver $viserver -VMHost $vmhost -destLoc $destloc -VerboseMode
 
$vms = VMware.VimAutomation.Core\Get-VM -Server $script:viconnection
 
$vmwarevm = $vms | ?{$_.Name -eq $vmname}
 
$vm = Get-VMDetails $vmwarevm
 
Migrate-VMWareVM $vm

Several notes about MVMC and these scripts:

  • This is an offline migration – the VM will be unavailable during the migration. The total amount of downtime depends on the size of the VMDK(s) to be migrated.
  • The script will only migrate a single server. You could wrap this into powershell tasks to migrate several servers simultaneously.
  • Hyper-V Gen1 servers only support booting from IDE. This script will search for the boot disk and attach it to IDE0, all other disks will be attached to a SCSI controller regardless of the source VM disk configuration.
  • Linux VM’s were not in scope as there are not reliable ways to gain write access to LVM volumes on Windows. Tests of CentOS6, Ubuntu12 and Ubuntu14 were successful. CentOS5 required IS components be pre-installed and modifications made to boot configuration. CentOS7 was unsuccessful due to disk configuration. The recommended way of migrating Linux VM’s is to pre-install IS, remove VMWare Tools, and modify boot configuration before migrating.
  • These scripts were tested running from a Server 2012 R2 VM migrating Server 2003 and Server 2012 R2 VM’s – other versions should work but have not been tested.
  • ESXi 5.5+ requires a connection to a vCenter server as storage SDK service is unavailable on the free version.

4 thoughts on “Automating VMWare to Hyper-V Migrations using MVMC

  1. Hi, very cool script. Can you tell me, if other credentials for hyper-v host and the vm are needed, how can this be realized in this script? Thanks.

    Regards Tom

    • It will connect to the destination Hyper-V host as whatever user account you’re running the script as. You could use Powershell’s remoting functionality to execute this as a different user on a different server, or simply load powershell as a user with appropriate permissions.

  2. Hello. I am getting a few errors and are hoping you can help:
    1.
    2017.01.17 09.31.58 —- Error loading Hyper-V cmdlets: Hyper-V Powershell cmdlets version 1.1 required. Found version: 2.0.0.0 (dont know if it maters)
    2.
    Hyper-V\New-VM : Failed to add device ‘Virtual Hard Disk’.
    Attachment ‘\\host.company.no\vm\AppsDev\disk-0.vhdx’ not found. Error: ‘The system cannot find the file specified.’.
    ‘AppsDev’ failed to add device ‘Virtual Hard Disk’. (Virtual machine ID 0F20A36D-5EF8-4687-8D27-6B56836AF509)
    ‘AppsDev’: Attachment ‘\\host.company.no\vm\AppsDev\disk-0.vhdx’ not found. Error: ‘The system cannot find the file specified.’ (0x80070002). (Virtual mach
    ine ID 0F20A36D-5EF8-4687-8D27-6B56836AF509)
    At C:\vmware-to-hyperv-convert\vmware-to-hyperv.ps1:510 char:12
    + … $destvm = Hyper-V\New-VM -ComputerName $VMHost -Name $vm.Name -Gene …
    (even tough the path its correct)
    3.
    Set-VMNetworkAdapterVlan : Cannot validate argument on parameter ‘VlanId’. The argument is null. Provide a valid value for the argument, and then try runnin
    g the command again.
    At C:\vmware-to-hyperv-convert\vmware-to-hyperv.ps1:532 char:64
    + … apter | Hyper-V\Set-VMNetworkAdapterVlan -Access -VlanId $nic.VlanId;
    + ~~~~~~~~~~~
    + CategoryInfo : InvalidData: (:) [Set-VMNetworkAdapterVlan], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.HyperV.PowerShell.Commands.SetVMNetworkAdapterVlan

    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : NotSpecified: (:) [New-VM], VirtualizationException
    + FullyQualifiedErrorId : Unspecified,Microsoft.HyperV.PowerShell.Commands.NewVM
    (we are using distributed switches)

    • It sounds like you’re using this script on a prior version of Windows (before 2012 R2). The script is untested in those versions, and some of the PowerShell cmdlets may need to be modified.

Leave a Reply to jeff Cancel reply

Your email address will not be published. Required fields are marked *