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.
[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]

Posted by Dag

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s