PowerShell script exchange
Post Reply
filipsmeets
Enthusiast
Posts: 37
Liked: 3 times
Joined: Jun 26, 2019 3:28 pm
Full Name: Filip Smeets
Contact:

Migrate Hyper-V VMs to vSphere with Instant VM Recovery

Post by filipsmeets »

Hi

We are investigating possible options to migrate workloads from Hyper-V to vSphere. We tried VMware Converter but there is no way to migrate a bunch of VMs at once. Considering there are +500 VMs, I would prefer not to use it.
Veeam Instant VM Recovery is also something we tested and It works great but it would still require some additional manual labor which we want to avoid.

We would like to automate VMware Tools installation on the recovered VMs.
Second, the VM gets recovered with an E1000 NIC and we would prefer to have the VMXNET3 adapter. Changing the NIC afterwards would require reconfiguration of IP setting in the Guest OS which makes it harder to automate.
Third problem, we would still need to do the storage vMotion (finalize recovery). Thinking about this, it would probably have to be the first step to be able to make changes to the VM.

Are there any better options to do this kind of migrations or do can we automate the above steps?

Thx.
PetrM
Veeam Software
Posts: 3626
Liked: 608 times
Joined: Aug 28, 2013 8:23 am
Full Name: Petr Makarov
Location: Prague, Czech Republic
Contact:

Re: Migrate Hyper-V VMs to vSphere with Instant VM Recovery

Post by PetrM » 1 person likes this post

Hi Filip,

I guess you could script it, for example it's possible to install VMware Tools via PowerCLI and as well to change network adapter. Instant Recovery itself including migration can be also managed by these PS cmdlets.

Thanks!
filipsmeets
Enthusiast
Posts: 37
Liked: 3 times
Joined: Jun 26, 2019 3:28 pm
Full Name: Filip Smeets
Contact:

Re: Migrate Hyper-V VMs to vSphere with Instant VM Recovery

Post by filipsmeets »

So this is what I came up with so far.
I'm still struggling to do these migrations in parallel instead of sequentially.
I could use -RunAsync but not sure if it's a good idea or even would provide some performance benefits.

Any suggestions would be welcome.

Code: Select all

function Move-Workload {
    <#
    .SYNOPSIS
        Performs a migration of VMs running on Hyper-V to vSphere.
    .DESCRIPTION
        Move-Workload uses Veeam's Instant VM Recovery capability to migrate VMs from Hyper-V to Vsphere.
        The script will accept one or multiple Computers/Servers to migrate. It will then lookup the latest restore
        point for each Computer and start a Veeam Instant VM Recovery. The restored VM on vSphere will run
        directly from the Backup Repository. After the Veeam Instant VM Recovery, a storage vMotion will be
        initiated to migrate the VM to production storage and finalize the migration.
    .PARAMETER ComputerName
        One or more computer names or VM names.
    .PARAMETER Datacenter
        The Datacenter to where you want to migrate.
    .PARAMETER Cluster
        The Cluster in the Datacenter to where you want to migrate.
    .PARAMETER ErrorLog
        When used with -LogErrors, specifies the file path and name to which failed computer names will be written.
    .PARAMETER LogErrors
        Specify this switch to create a text log file of computers that could not be migrated.
    .EXAMPLE
        PS C:\> Get-Content "E:\Scripts\Computers.csv" | Move-Workload -Datacenter 'DCR2' -Cluster 'Workloads'
        The command will read the list of computernames/hostnames from the CSV file and then migrate each of them
        to the Datacenter and Cluster provided.
    .EXAMPLE
        PS C:\> Move-Workload Computer1,Computer2 -Datacenter 'DCR2' -Cluster 'Workloads' -LogErrors -Verbose
    .INPUTS
        Inputs (if any)
    .OUTPUTS
        Output (if any)
    .NOTES
        General notes
    #>

    [CmdletBinding()]
    param (
        # Computer(s) you would like to move
        [Parameter(Mandatory = $true,ValueFromPipeline = $true)]
        [ValidateCount(1,10)]
        [Alias('hostname')]
        [string[]]
        $ComputerName,

        # The datacenter where you want to move the workload to.
        [Parameter(Mandatory = $true)]
        [string]
        $Datacenter,

        # The Cluster where you want to move the workload to.
        [Parameter(Mandatory = $true)]
        [string]
        $Cluster,

        # Errorlog
        [Parameter()]
        [string]
        $ErrorLog = 'E:\Scripts\ErrorLog.txt',

        # Enable error logging
        [Parameter()]
        [switch]
        $LogErrors
    )
    
    begin {
        Write-Verbose "Log name is $ErrorLog"

        #Connect to local Veeam Backup Server
        Connect-VBRServer

        #Connect to vSphere
        $credVC = Get-Credential -Message "Provide credentials to connect to vCenter"

        Set-PowerCLIConfiguration -InvalidCertificateAction Ignore -Confirm:$false -Scope User -ParticipateInCeip $false
        Connect-VIServer -Server vcenterfqdn -credential $credVC
    }
    
    process {
        foreach ($Computer in $ComputerName) {

            Write-Verbose "Querying computer $Computer for restorepoints"
            $restorepoint = Get-VBRRestorePoint -Name $Computer | Sort-Object $_.creationtime -Descending | Select-Object -First 1

            if ($restorepoint -eq $null) {
                Write-Warning "Could not start migration for server $Computer. No restore points found."
                
                if ($LogErrors) {
                    $Computer + " " + "No restore points found" | Out-File $ErrorLog -Append
                    Write-Warning "Logged to $ErrorLog"
                }
            }
            else {
                Write-Verbose "Latest available restore point for server $Computer was created on $($restorepoint.CreationTime)"

                Write-Verbose "Selecting the most suitable ESXi host and Datastore based on available resources"
                $server = Get-VBRServer -Name (Get-Datacenter -Name $Datacenter | Get-Cluster -Name $Cluster |Get-VMHost -State Connected |Sort-Object $_.MemoryUsageMhz -Descending | Select-Object -ExpandProperty Name)
                $datastore = Find-VBRViDatastore -Server $server -Name "*HSA*" |Sort-Object -Property FreeSpace -Descending | Select-Object -First 1

                Write-Verbose "Server $Computer will be migrated to VMware Host $($server.Name) and stored on Datastore $datastore"

                Write-Verbose "Start Veeam Instant VM Recovery of server $Computer"
                Start-VBRViComputerInstantRecovery -RestorePoint $restorepoint -Server $server -CacheDatastore $datastore -PowerOnAfterRestoring:$false -ConnectVMToNetwork:$false -Reason "VM migration"

                Write-Verbose "Veeam Instant VM Recovery for server $Computer completed."
                                        
                #Migrate to production site:
                Write-Verbose "Starting storage vMotion of server $Computer to production Datastore"
                $entity = Find-VBRViEntity -Name $Computer

                Start-VBRQuickMigration -Entity $entity -server $server -datastore $datastore
                Write-Verbose "Server $Computer has been moved to production Datastore"

                #Stop Instant VM Recovery
                Write-Verbose "Stopping Veeam Instant VM Recovery"            
                Get-VBRInstantRecovery |Where-Object{$_.VmName -like $Computer} |Stop-VBRInstantRecovery
                Write-Verbose "Server $Computer has been successfully migrated"

                $Computer + " " + "has been successfully migrated on " + (Get-Date ) | Out-File $ErrorLog -Append
            }
        }
    }
    
    end {        
        #Disconnect from local Veeam Backup Server
        Disconnect-VBRServer

        #Disconnect from vCenter
        Disconnect-VIServer -Confirm:$false
    }
}
foggy
Veeam Software
Posts: 21139
Liked: 2141 times
Joined: Jul 11, 2011 10:22 am
Full Name: Alexander Fogelson
Contact:

Re: Migrate Hyper-V VMs to vSphere with Instant VM Recovery

Post by foggy » 1 person likes this post

Hi Filip, we have a dedicated subforum for everything PS scripting-related. Moved this entire automation topic there. Thanks!
filipsmeets
Enthusiast
Posts: 37
Liked: 3 times
Joined: Jun 26, 2019 3:28 pm
Full Name: Filip Smeets
Contact:

Migrate Hyper-V VMs to vSphere with Instant VM Recovery

Post by filipsmeets »

Hi guys

I'm trying to automate a migration from Hyper-V to vSphere by using Veeam Instant VM Recovery.

It's working but it will only do one VM at a time.
I tried adding -RunAsync for the Quick migration but not sure if it's a good approach or even going to provide me any performance benefits.
If I would use -RunAsync, I would also need to incorporate a way to monitor when the quick migration job is done and then stop the Instant VM Recovery.

This what I have so far.

Any help or suggestions are more then welcome.
We need to migrate +/- 600 VMs.

Code: Select all

function Move-Workload {
    <#
    .SYNOPSIS
        Performs a migration of VMs running on Hyper-V to vSphere.
    .DESCRIPTION
        Move-Workload uses Veeam's Instant VM Recovery capability to migrate VMs from Hyper-V to Vsphere.
        The script will accept one or multiple Computers/Servers to migrate. It will then lookup the latest restore
        point for each Computer and start a Veeam Instant VM Recovery. The restored VM on vSphere will run
        directly from the Backup Repository. After the Veeam Instant VM Recovery, a storage vMotion will be
        initiated to migrate the VM to production storage and finalize the migration.
    .PARAMETER ComputerName
        One or more computer names or VM names.
    .PARAMETER Datacenter
        The Datacenter to where you want to migrate.
    .PARAMETER Cluster
        The Cluster in the Datacenter to where you want to migrate.
    .PARAMETER ErrorLog
        When used with -LogErrors, specifies the file path and name to which failed computer names will be written.
    .PARAMETER LogErrors
        Specify this switch to create a text log file of computers that could not be migrated.
    .EXAMPLE
        PS C:\> Get-Content "E:\Scripts\Computers.csv" | Move-Workload -Datacenter 'DCR2' -Cluster 'Workloads'
        The command will read the list of computernames/hostnames from the CSV file and then migrate each of them
        to the Datacenter and Cluster provided.
    .EXAMPLE
        PS C:\> Move-Workload Computer1,Computer2 -Datacenter 'DCR2' -Cluster 'Workloads' -LogErrors -Verbose
    .INPUTS
        Inputs (if any)
    .OUTPUTS
        Output (if any)
    .NOTES
        General notes
    #>

    [CmdletBinding()]
    param (
        # Computer(s) you would like to move
        [Parameter(Mandatory = $true,ValueFromPipeline = $true)]
        [ValidateCount(1,10)]
        [Alias('hostname')]
        [string[]]
        $ComputerName,

        # The datacenter where you want to move the workload to.
        [Parameter(Mandatory = $true)]
        [string]
        $Datacenter,

        # The Cluster where you want to move the workload to.
        [Parameter(Mandatory = $true)]
        [string]
        $Cluster,

        # Errorlog
        [Parameter()]
        [string]
        $ErrorLog = 'E:\Scripts\ErrorLog.txt',

        # Enable error logging
        [Parameter()]
        [switch]
        $LogErrors
    )
    
    begin {
        Write-Verbose "Log name is $ErrorLog"

        #Connect to local Veeam Backup Server
        Connect-VBRServer

        #Connect to vSphere
        $credVC = Get-Credential -Message "Provide credentials to connect to vCenter"

        Set-PowerCLIConfiguration -InvalidCertificateAction Ignore -Confirm:$false -Scope User -ParticipateInCeip $false
        Connect-VIServer -Server vcenterfqdn -credential $credVC
    }
    
    process {
        foreach ($Computer in $ComputerName) {

            Write-Verbose "Querying computer $Computer for restorepoints"
            $restorepoint = Get-VBRRestorePoint -Name $Computer | Sort-Object $_.creationtime -Descending | Select-Object -First 1

            if ($restorepoint -eq $null) {
                Write-Warning "Could not start migration for server $Computer. No restore points found."
                
                if ($LogErrors) {
                    $Computer + " " + "No restore points found" | Out-File $ErrorLog -Append
                    Write-Warning "Logged to $ErrorLog"
                }
            }
            else {
                Write-Verbose "Latest available restore point for server $Computer was created on $($restorepoint.CreationTime)"

                Write-Verbose "Selecting the most suitable ESXi host and Datastore based on available resources"
                $server = Get-VBRServer -Name (Get-Datacenter -Name $Datacenter | Get-Cluster -Name $Cluster |Get-VMHost -State Connected |Sort-Object $_.MemoryUsageMhz -Descending | Select-Object -ExpandProperty Name)
                $datastore = Find-VBRViDatastore -Server $server -Name "*HSA*" |Sort-Object -Property FreeSpace -Descending | Select-Object -First 1

                Write-Verbose "Server $Computer will be migrated to VMware Host $($server.Name) and stored on Datastore $datastore"

                Write-Verbose "Start Veeam Instant VM Recovery of server $Computer"
                Start-VBRViComputerInstantRecovery -RestorePoint $restorepoint -Server $server -CacheDatastore $datastore -PowerOnAfterRestoring:$false -ConnectVMToNetwork:$false -Reason "VM migration"

                Write-Verbose "Veeam Instant VM Recovery for server $Computer completed."
                                        
                #Migrate to production site:
                Write-Verbose "Starting storage vMotion of server $Computer to production Datastore"
                $entity = Find-VBRViEntity -Name $Computer

                Start-VBRQuickMigration -Entity $entity -server $server -datastore $datastore
                Write-Verbose "Server $Computer has been moved to production Datastore"

                #Stop Instant VM Recovery
                Write-Verbose "Stopping Veeam Instant VM Recovery"            
                Get-VBRInstantRecovery |Where-Object{$_.VmName -like $Computer} |Stop-VBRInstantRecovery
                Write-Verbose "Server $Computer has been successfully migrated"

                $Computer + " " + "has been successfully migrated on " + (Get-Date ) | Out-File $ErrorLog -Append
            }
        }
    }
    
    end {        
        #Disconnect from local Veeam Backup Server
        Disconnect-VBRServer

        #Disconnect from vCenter
        Disconnect-VIServer -Confirm:$false
    }
}
oleg.feoktistov
Veeam Software
Posts: 2010
Liked: 670 times
Joined: Sep 25, 2019 10:32 am
Full Name: Oleg Feoktistov
Contact:

Re: Migrate Hyper-V VMs to vSphere with Instant VM Recovery

Post by oleg.feoktistov »

Hi Filip,

-RunAsync parameter is an equivalent of the UI bulk instant restore. So. if you configure an offset of concurrent tasks for your backup proxies and repositories depending on the resources these servers have, this option might be the way to go. As you correctly noticed, you will still need to monitor instant recovery and migration sessions every N times of iterations (where N is a number of concurrent tasks). Instant recovery sessions - to make migrations start only for machines, whose mount states are "Mounted", and migration sessions - to then stop the instant recovery and unmount repositories mounted as datastores from vSphere (if not needed for other migrations).
By the way, I'd advise to use Start-VBRViInstantRecoveryMigration cmdlet instead to finalize your instant recovery migrations to vSphere. It accepts instant recovery object, so you can pick up precise mount point shown in VBR console instead of skimming through vSphere infrastructure for the VMs you mounted.


Thanks,
Oleg
filipsmeets
Enthusiast
Posts: 37
Liked: 3 times
Joined: Jun 26, 2019 3:28 pm
Full Name: Filip Smeets
Contact:

Re: Migrate Hyper-V VMs to vSphere with Instant VM Recovery

Post by filipsmeets »

Does the command Start-VBRViInstantRecoveryMigration work if you are coming from Hyper-V?
oleg.feoktistov
Veeam Software
Posts: 2010
Liked: 670 times
Joined: Sep 25, 2019 10:32 am
Full Name: Oleg Feoktistov
Contact:

Re: Migrate Hyper-V VMs to vSphere with Instant VM Recovery

Post by oleg.feoktistov »

It does. Just make sure to pass destination containers like resource pool, folder, datastore even if -ToTarget parameter is specified. Otherwise, VMs will be migrated to the default ones. Thanks!
Post Reply

Who is online

Users browsing this forum: No registered users and 9 guests