So now we covered all the basic and the preparation for the migration it’s time for the actual migration. We had the luxury we could start with the acceptance environment which had his own VRF(Bridge-Domain/subnets/EPGs) within ACI so we could really test our migration.


As a lot of environments nowadays, this environment contained sensitive data. Therefore, at no point the environment security must be compromised. The first migration strategies were focused on a L2 Bridge between ACI and NSX to migrate the VMs. With this bridge we would be able to live vMotioned VMs (via Cross vCenter vMotion) from ACI to NSX. To make this work we had to write a script that sets the right tags to each VM after migration so the VM would fall in the proper security group.

But as soon as we talked more with the customer, we understand that they rather had downtime because a few applications were so sensitive that even the slightest ping fail would result in a crashing application. It’s easier to shut it down and restart everything than to fix/troubleshoot. This made the migration a lot easier.

We came up with the following procedure to do this. Per item I will highlight how we automated this;

PowerOff and De-register VMs in ACI vCenter

$Virtualmachines = Import-Csv -Path "VMs-Acceptatie.csv"

#connect oude vCenter
Connect-VIServer $vcenter

Get-VM -Name $ |ForEach-Object -Process {
 $Name = $
   $vm = Get-VM $name -ErrorAction Stop
   'poweredon' {
  Shutdown-VMGuest -VM $vm -Confirm:$false
   while($vm.PowerState -eq 'PoweredOn'){
  sleep 5
   $vm = Get-VM -Name $Name
   Default {
   Write-Host "VM '$($vm)' is not powered on!"
   Write-Host "$($vm) has shutdown. It will now be removed from inventory."
   Remove-VM $vm -Confirm:$false -Verbose
   Write-Host "VM '$($vmName)' not found!"
#disconnect vCenter
Disconnect-VIServer * -force -Confirm:$false

Creating Logical segments in NSX incl. gateway

We created the Logical segments manualy. Although they are pretty easy to create via API. We only had 2 subnets therefore not really a need to automate this. After creation we checked if the BGP routes were correctly published on the firewalls and configured the DHCP relay on the specific subnets.

Register VMs in the new vCenter and reconfigure the vNIC

This was a verry simple powerhell script to register the VMs in the new vCenter and change the networkadapter to the new logical segment.

$vmlist = Import-Csv -Path "VMs-Acceptatie.csv"

Connect-VIServer $vcenter

foreach ($vm in $vmlist){
$ResourcePool = Get-ResourcePool $vm.RP
$Folder = get-folder -id $vm.FolderID

New-VM -VMFilePath $vm.VMX -Verbose -Resourcepool $ResourcePool -Location $Folder

#Change NIC
foreach ($vm in $vmlist){
get-vm $vm.vm |Get-NetworkAdapter | Where-Object {$_.Name -eq "Network adapter 2"} | Set-NetworkAdapter  -NetworkName $vm.NewPortgroup -Confirm:$false

#disconnect vCenter
Disconnect-VIServer * -force -Confirm:$false

Tag the VMs in Postman

We wanted to tag the VMs in NSX in an automatic fashion. As described, we made a CSV which contains all the info so with the postman runner we were able to use this as input for our script

We created a new collection in postman which contained two restAPI calls

  1. Retrieve the external ID of the VM within NSX [Get-VM]
  2. Set the tags to this external ID [Set-Tags]

Let’s take a look at the GET-VM;

There is no actual body in this script, but there is some information in tests option. You can see we populate the VMnaam from the inputfile (Our CSV). And we filter the external_ID from the result/response we get from the API.

The next API CALL in the API gets this external ID and add the tags from the CSV to the respective VM.

In the pre-request we define the variables from the CSV.

Because of this definition in the pre-request, we can use them in the body. As you can see the External_ID doesn’t need to be defined because this is an environment variable which is set from previous API call.

To complete this RESTAPI calls we build a tests to validate that the tags were successful set.

The original article was posted on:

Ruud Harreman Virtualization Consultant

Let's talk!

Knowledge is key for our existence. This knowledge we use for disruptive innovation and changing organizations. Are you ready for change?

"*" indicates required fields

First name*
Last name*