Adding the host to Distributed switch and Mapping the VMs [V1]

Posted by

Hello 2020 and my fist technical post of  the year.

Use case:

You have built a new vCenter from scratch and would like to move host from an existing vCenter server to this one. As a preparation for this migration you performed following steps

1Created Network mapping of all VMs in the source vCenter server
2Exported the Distributed switch configuration from the source vCenter server
3Imported the Distributed switch configuration to the new vCenter server
4Added ESXi hosts in the New vCenter server to their respective Datacenter and cluster

However, you are still left with mammoth task of adding the host to Distributed switch and Mapping the VMs to a Distributed PortGroups. If you have not completed the Step 1 above, you may do so using the code below

Code to create Network mapping:

Start-Transcript -Append -Path "$env:USERPROFILE\Documents\NetMap.log"
$vCenterIP = Read-Host "Enter vCenter IP or Name where the operation needs to be executed"
$myDatacenter = Read-Host "Enter Datacenter Name where the operation needs to be executed"
$Cluster = Read-Host "Enter Cluster Name where the operation needs to be executed"
Connect-VIServer $vCenterIP
Get-Datacenter -Name $myDatacenter | Get-Cluster -Name $Cluster |Get-VM | Get-NetworkAdapter | Select @{N="VM";E={$_.Parent.Name}},Name,NetworkName|export-Csv  "$env:USERPROFILE\Documents\Network_Map.csv" -NoTypeInformation
Disconnect-viserver -confirm:$false
Stop-Transcript

Script Workflow:

Code:

This script makes use of Auto assign vmnic to DVS uplink. Due to this there is no way to specify vmnic to uplink mapping. Hence, do not use in an environment where vmnic to uplink mapping is required to be a constant. Use V2 Script instead

Do not use the script without testing it in your Test/Dev environment

Start-Transcript -Append -Path "$env:USERPROFILE\Documents\DVScopy.log"
$vCenterIP = Read-Host "Enter vCenter IP or Name where the operation needs to be executed"
$myDatacenter = Read-Host "Enter Datacenter Name where the operation needs to be executed"
$Cluster = Read-Host "Enter Cluster Name where the operation needs to be executed"
$NewDVS = Read-Host "Enter a Name for the DVS in the New vCenter"
Connect-VIServer $vCenterIP
[uint16]$Choice=1
While ($Choice -ne 0)
{
Write-Host -ForegroundColor Red "Step 1,2 and 3 are expected to be run sequentially. Unless you have migrated all the VM to $NewDVS and would like to execute Step 2 to move additional Nic"
Write-Host -ForegroundColor Green "What would you like to do?"
Write-Host -ForegroundColor Green "1: Add Hosts to $NewDVS"
Write-Host -ForegroundColor Green "2: Move Physical Nics to $NewDVS"
Write-Host -ForegroundColor Green "3: Move VMs to $NewDVS"
Write-Host -ForegroundColor Green "0: Exit"
[uint16]$Choice=Read-Host "Select the operation you would like to perform [0]"
$hostnames=Get-Datacenter -Name $myDatacenter | Get-Cluster -Name $Cluster | Get-VMHost
$hostnames=$hostnames.name
switch($Choice)
{
   1 {
        Write-Host -ForegroundColor Green "You have selected to add Hosts to $NewDVS"
        ################Adding the Host to the new DVS by reading the host list########################
        ForEach ($hostname in $hostnames)
        {
        Get-VDSwitch -Name $NewDVS|Add-VDSwitchVMHost -VMHost $hostname -Confirm:$false
        Write-Host -ForegroundColor Green "Added $hostname to $NewDVS"
        }
      }
   2 {
        Write-Host -ForegroundColor Green "You have selected to Move Physical Nics to $NewDVS"
        ################Move Physical Nics######################################
        $NicName=Read-Host "Enter a Name of the uplink to move[vmnic0]"
        Write-Host -ForegroundColor Red "Moving uplink $NicName for all Host in the  slected cluster.This can lead to Network outage"
        $Execute ="no"
        While ($Execute -ne "yes")
        {
        $Execute =Read-Host "Should I proceed[yes]"
        }
        ForEach ($hostname in $hostnames)
        {
         $vmhostNetworkAdapter = Get-VMHostNetworkAdapter -Physical|Where-Object {($_.VMHost.Name -eq $hostname) -and ($_.Name -in $NicName)}
         Get-VDSwitch $NewDVS | Add-VDSwitchPhysicalNetworkAdapter -VMHostNetworkAdapter $vmhostNetworkAdapter -Confirm:$false
         Write-Host -ForegroundColor Green "Moved $NicName for $hostname to $NewDVS"
        }
     }
   3 {
        Write-Host -ForegroundColor Green "You have selected to Move VMs to $NewDVS"
        ###################Move VMs#########################
        #Validation Prompt
        $Execute = "no"
        While ($Execute -ne "yes")
        {
        Write-Host -ForegroundColor Red "Moving VMs from one Portgroup to another will lead to a brief network outage."
        Write-Host -ForegroundColor Red "Validate and confirm the Physical Nic placement for Hosts on $NewDVS before proceding."
        $Execute=Read-Host "Would you like to proceed further with VM placement[yes]"
        }
        $NetMap = Import-Csv $env:USERPROFILE\Documents\Network_Map.csv
        $VMs = Get-Datacenter -Name $myDatacenter | Get-Cluster -Name $Cluster |Get-VM
        #Virtual Machine placement
        ForEach ($VM in $VMs)
        {
            if($VM.Name -in $NetMap.VM)
            {
            $NetAdapters=Get-VM $VM | Get-NetworkAdapter
                ForEach ($NetAdapter in $NetAdapters)
                {
                    $NetName=$NetMap | Where-Object{($_.VM -eq $VM.Name) -and ($_.Name -eq $NetAdapter.Name)}
                    $NetName=$NetName.NetworkName
                    $error.clear()
                    try
                        {
                            Set-NetworkAdapter -NetworkAdapter $NetAdapter -Portgroup $NetName -Confirm:$false
                        }catch{}
                    if(!$error)
                        {
                            Write-Host -ForegroundColor Green "Moved $NetAdapter for $VM to $NewDVS PortGroup $NetName"
                        }
                    else
                        {
                            Write-Host -ForegroundColor red "Error processing $VM"
                        }
                }
             }
            else
            {
                Write-Host -ForegroundColor red "Network mapping not found for $VM"
            }
        }
     }
   default
        {
            $Choice=0
        }
}
}
Disconnect-viserver -confirm:$false
Stop-Transcript

Sample Network_Map.csv

"VM","Name","NetworkName"
"Test2","Network adapter 1","DPortGroup 1"
"Test2","Network adapter 2","DPortGroup 2"
"win2k12r2 (1)","Network adapter 1","DPortGroup"
"Test1","Network adapter 1","DPortGroup 1"
"psc67u3","Network adapter 1","DPortGroup"

Feel free to provide your feedback in comments

One comment

  1. The code above is lacking the ability to map a vmnic to a defined dvs uplink. This can lead to serious issues in environments. For example when you have a DVS with 4 uplinks but only two are used to assign vmnic.
    Stay tuned for version 2 that will factor above

Comments are closed.