We recently came across an issue where we needed to migrate VMware ESXi hosts from standard vSwitches to distributed vSwitches at build time and before putting the hosts into production. This is straight forward from vCenter by just using the normal migration wizards, but proved to be a little trickier from command line:
- On a single NIC host the uplink migration has to be done at the same time as port groups and service consoles / VMkernels.
- This can not be done from the ESXi side (happy to be proven wrong on this point) but has to be managed from VC.
- In addition this had to be handled by Ansible automated ESXi / VC build playbooks, preferably without involving any other intermediary build hosts.
The conclusion was the migration can be handled by using PowerCLI under Powershell. Microsoft have this year released Powershell for Linux – which meant it could be installed on the Ansible build hosts. PowerCLI can then just be added to the same host:
Once the pre-requisites are in place the following script will handle the migration. Input parameters are named:
- vchost: IP address of VC host
- vcuser: VC user account
- vcpass: VC password
- esxihosts: comma delimited list of ESXi hosts to migrate
- dvswitchname: name of distributed vSwitch. The script assumes this has already been created through other means, e.g. the Ansible VMware modules.
param( [String] $vchost, [String] $vcuser, [String] $vcpass, [String] $esxihosts, [String] $dvswitchname ) # Stop spam Set-PowerCLIConfiguration -Scope User -ParticipateInCEIP $false # Ignore certificates Set-PowerCLIConfiguration -InvalidCertificateAction ignore -confirm:$false # VC connectivity Write-Host "Connecting to VC host " $vchost Connect-VIServer -Server $vchost -User $vcuser -Pass $vcpass # Array of esxi hosts $esxihostarray = $esxihosts -split ',' foreach ($esxihost in $esxihostarray) { $dvswitch = Get-VDSwitch $dvswitchname # Add ESXi host to dvSwitch Write-Host "Adding" $esxihost "to" $dvswitchname Add-VDSwitchVMHost -VMHost $esxihost -VDSwitch $dvswitch $management_vmkernel = Get-VMHostNetworkAdapter -VMHost $esxihost -Name "vmk0" $management_vmkernel_portgroup = Get-VDPortgroup -name "Management Network" -VDSwitch $dvswitchname # Migration esxi host networking to dvSwitch Write-Host "Adding vmnic0 to" $dvswitchname $esxihostnic = Get-VMHost $esxihost | Get-VMHostNetworkAdapter -Physical -Name vmnic0 Add-VDSwitchPhysicalNetworkAdapter -VMHostPhysicalNic $esxihostnic -DistributedSwitch $dvswitch -VMHostVirtualNic $management_vmkernel -VirtualNicPortgroup $management_vmkernel_portgroup -Confirm:$false } Disconnect-VIServer -Server $global:DefaultVIServers -Force -Confirm:$false
The script can be ran either directly, or by a “local_action shell” from Ansible:
/usr/bin/pwsh esxi-dvs-mgmt.ps1 -vchost [VC host IP] -vcuser [VC user] -vcpass [VC password] -esxihosts "[ESXihost1,ESXihost2]" -dvswitchname [dvSwitch name]