VMware to Hyper-V Migration with MAT and my addons
Today I was on Sommarkollo at Microsoft Sweden and speaking on the event and this was the last of two sessions about the MAT (Migration Automation Toolkit).
This automation tool that I first got to know about at MMS 2013 in Las Vegas (sadly it looks like there will be no more MMS 🙁 but that is another story ) in the session held by “Migration Mark” and Matt McSpirit WS-B325 and there in the video about 41 minutes into I ask about how the MAT take care of IP addresses on the migrated VM´s and they answered me that is not part of the MAT yet! And well I would say that this would be quite painful to migrate 100-200 VM´s with this automation tool and still have to enter IP settings for each migrated vm manually!!
But I have an example on how that can be done, I have not integrated it into the MAT scripts yet but it automates the collection of not just the IP addresses but also dns,subnet and gateway.
The information is available via the PowerCLI from the vCenter and here I show you how you can collect all that info after you have got the migration list
# Collect Networking info from VM´s # # Niklas Akerlund / 2013-07-01 if(!(Get-PSSnapin "VMware.VimAutomation.Core" -ErrorAction SilentlyContinue)){ Add-PSSnapin "VMware.VimAutomation.Core" } $MigVMs = Get-Content "d:\mat\vmlist.txt" $VMNetConf = @() Connect-VIServer vCenter.vniklas.com remove-module Hyper-V -ErrorAction SilentlyContinue foreach ($MigVM in $MigVMs){ $VM = Get-VM $MigVM.Split(".")[0] #write-host $VM #$VM = Get-VM $VM $VMNics = Get-VMGuestNetworkInterface $VM | where {$_.IP -ne $null -and $_.IPPolicy -eq "Static"} foreach ($VMNic in $VMNics){ $VMNetAdapter = Get-NetworkAdapter -VM $VMNic.VM -Name $VMNic.NetworkAdapter $obj = [PSCustomObject]@{ VMName = $VM.Name NetworkName = $VMNetAdapter.NetworkName IP = $VMNic.Ip Subnet = $VMNic.SubnetMask DNS = [string]$VMNic.Dns GW = $VMNic.DefaultGateway } $VMNetConf +=$obj } } $VMNetConf | Export-csv -Path d:\mat\vmniclist.txt -NoTypeInformation -NoClobber -UseCulture
Here you can see the csv file after it has run in my test environment, one thing that I will extend with after discussing with some folks is the vlan number the port group the vm is connected to so that can be configured on the other side also.
And then I also with the possibility that there is in Hyper-V 2012, configure the network on the guest from the host, this requires that the virtual machine has the latest integration components installed. Ravikanth has done a blog post about how his function, I have added the possibility to run it from a remote computer
# Set-VMNetworkConfiguration # Orginial by Ravikanth http://www.ravichaganti.com/blog/?p=2766 # # Added computername to remotly set IP to guest from hosts # Niklas Akerlund Function Set-VMNetworkConfiguration { [CmdletBinding()] Param ( [Parameter(Mandatory=$true, Position=1, ParameterSetName='DHCP', ValueFromPipeline=$true)] [Parameter(Mandatory=$true, Position=0, ParameterSetName='Static', ValueFromPipeline=$true)] [Microsoft.HyperV.PowerShell.VMNetworkAdapter]$NetworkAdapter, [Parameter(Mandatory=$true, Position=2, ParameterSetName='DHCP', ValueFromPipeline=$true)] [Parameter(Mandatory=$true, Position=5, ParameterSetName='Static', ValueFromPipelineByPropertyName=$true)] [String[]]$ComputerName=@(), [Parameter(Mandatory=$true, Position=1, ParameterSetName='Static')] [String[]]$IPAddress=@(), [Parameter(Mandatory=$false, Position=2, ParameterSetName='Static')] [String[]]$Subnet=@(), [Parameter(Mandatory=$false, Position=3, ParameterSetName='Static')] [String[]]$DefaultGateway = @(), [Parameter(Mandatory=$false, Position=4, ParameterSetName='Static')] [String[]]$DNSServer = @(), [Parameter(Mandatory=$true, Position=0, ParameterSetName='DHCP')] [Switch]$Dhcp ) $VM = Get-WmiObject -Namespace 'root\virtualization\v2' -Class 'Msvm_ComputerSystem' -ComputerName $ComputerName | Where-Object { $_.ElementName -eq $NetworkAdapter.VMName } $VMSettings = $vm.GetRelated('Msvm_VirtualSystemSettingData') | Where-Object { $_.VirtualSystemType -eq 'Microsoft:Hyper-V:System:Realized' } $VMNetAdapters = $VMSettings.GetRelated('Msvm_SyntheticEthernetPortSettingData') $NetworkSettings = @() foreach ($NetAdapter in $VMNetAdapters) { if ($NetAdapter.Address -eq $NetworkAdapter.MacAddress) { $NetworkSettings = $NetworkSettings + $NetAdapter.GetRelated("Msvm_GuestNetworkAdapterConfiguration") } } if ($Dhcp) { $NetworkSettings[0].DHCPEnabled = $true } else { $NetworkSettings[0].DHCPEnabled = $false $NetworkSettings[0].IPAddresses = $IPAddress $NetworkSettings[0].Subnets = $Subnet $NetworkSettings[0].DefaultGateways = $DefaultGateway $NetworkSettings[0].DNSServers = $DNSServer $NetworkSettings[0].ProtocolIFType = 4096 } $Service = Get-WmiObject -Class "Msvm_VirtualSystemManagementService" -Namespace "root\virtualization\v2" -ComputerName $ComputerName $setIP = $Service.SetGuestNetworkAdapterConfiguration($VM, $NetworkSettings[0].GetText(1)) if ($setip.ReturnValue -eq 4096) { $job=[WMI]$setip.job while ($job.JobState -eq 3 -or $job.JobState -eq 4) { start-sleep 1 $job=[WMI]$setip.job } if ($job.JobState -eq 7) { write-host "Success" } else { $job.GetError() } } elseif($setip.ReturnValue -eq 0) { Write-Host "Success" } }
And here is the script that I run to configure the VM´s after the MAT has done the conversions, and yes as Mark says about MAT, there is room for improvements here also of course, As you can see I start with injecting the latest integration components into the VM, the sleep cmdlet is used to get the vm fully booted and integration components installed and then an reboot inside the VM.
# Configure and set VM after Conversion # # Niklas AKerlund / 2013-07-01 # Function import . .\Set-VMNetworkConfiguration.ps1 $VMNICs = Import-CSV -Path D:\mat\vmniclist.txt -Delimiter ";" $ConvertedVMs = Get-Content -Path D:\mat\VMlist.txt # Configure each vm before starting foreach ($ConvertedVM in $ConvertedVMs){ $VM = Get-VM $ConvertedVM.Split(".")[0] write-host $VM.Name #patch each VM with latest Integration Tools $virtualHardDiskToUpdate =($VM | Get-VMHardDiskDrive).path $integrationServicesCabPath ="C:\Windows\vmguest\support\amd64\Windows6.x-HyperVIntegrationServices-x64.cab" #Mount the VHD $diskNo=(Mount-VHD -Path $virtualHardDiskToUpdate –Passthru).DiskNumber #Get the driver letter associated with the mounted VHD, note this assumes it only has one partition if there are more use the one with OS bits $driveLetter=(Get-Disk $diskNo | Get-Partition | where Size -GT 100MB).DriveLetter #Check to see if the disk is online if it is not online it if ((Get-Disk $diskNo).OperationalStatus -ne 'Online'){Set-Disk $MountedVHD.Number -IsOffline:$false -IsReadOnly:$false} #Install the patch Add-WindowsPackage -PackagePath $integrationServicesCabPath -Path ($driveLetter + ":\") #Dismount the VHD Dismount-VHD -Path $virtualHardDiskToUpdate Start-VM -VM $VM Start-Sleep -Seconds 300 # Wait for the Integration components being installed and the server reboot (reboot requires interaction or automatic script inside VM or you will have to do an unclean poweroff Start-VM -VM $VM # check that the migrated VM actually has ic that responds do { $notok = Get-VMIntegrationService -VM $VM | Select -First 1 | where PrimaryStatusDescription -eq "OK" } while( $notok -eq $null) # COnfigure NICs foreach ($VMNic in $VMNICs){ write-host "Configuring" if($VMNIC.VMName -eq $VM.Name){ if(!(Get-VMNetworkAdapter -VM $VM)){ $VMNetAdapter = Add-VMNetworkAdapter -VM $VM -SwitchName $VMNic.NetworkName -Passthru $VMNetAdapter | Set-VMNetworkConfiguration -IPAddress $VMNic.IP -DefaultGateway $VMNic.GW -Subnet $VMNic.SubnetMask -DNSServer $VMNic.Dns -ComputerName HV03 }else { Connect-VMNetworkAdapter -VMName $VM.Name -SwitchName $VMNic.NetworkName $VMNetAdapter = Get-VMNetworkAdapter -VM $VM write-host "connecting $VMNic.NetworkName " $VMNetAdapter | Set-VMNetworkConfiguration -IPAddress $VMNic.IP -DefaultGateway $VMNic.GW -Subnet $VMNic.Subnet -DNSServer $VMNic.DNS -ComputerName HV03 } } } }
And after running as you can see in the Hyper-V manager I have the right IP on the VM (and if you check inside the VM, you will see that the dns,subnet and gateway also has been set correctly.
Comments
[…] in Hyper-V 2012 R2 and System Center VMM 2012 R2 and also migration and the different tools. I did a blog post about my customisations of the MAT that was running with MVMC and my way to solve …and after my blog there have come an updated version of the MAT that do handle the […]
Hello.I’m trying to use Set-VMNetworkConfiguration on a linux vm but i get an wmi error.The integration services are installed.Any ideas?Have you made it work on linux?
Thanks in advanced!
Hi Niklas,
can you say me how i can set the alternate DNS Server with “Set-VMNetworkConfiguration” Script?
Thx for your Feedback.