VMware Cloud Community
mark_chuman
Hot Shot
Hot Shot

Script to migrate cluster from one vCenter to another vCenter

Attached is a script I use to migrate an ESXi cluster from one vCenter to another.  I'll be updating the script (will add VM folder locations and attributes, more qa, root credential storage - PASSWORD IS STORED IN TRANSCRIPT FILE - so, adjust this in script or cleanse transcript after run), but for now it handles HA settings, DRS settings, EVC, DRS vm rules (affinity/anti), folder import/export, permissions (datacenter, cluster, host, folder and vm) and maybe some other things I left out.  Does not deal with dvs as we use local vswitches.

You'll need two VCs and a cluster you want to migrate.  The script does not create the datacenter in the destination VC, but it will create the cluster, disconnect, remove an add the hosts.

I hope it can help someone as I've mainly been on the receiving end with regards to help from this forum Smiley Happy.  Special note to Luc for a lot of the items in the script (folder functions, splat etc Smiley Happy).

Just unzip to a directory and run with powercli (requested credentials must have VC privs to disconnect hosts etc.).

As always with offerings, use at your own risk!

*Using to go from 5.0 to 5.5.

90 Replies
Romino
Contributor
Contributor

I didn't manage to make it work with the virtual Distributed Switch so I reconnected back to the old vCenter. Fortunately, no harm to the production environment has been done. Would it be possible to implement the vDS migration into this awesome script in future? Thank you very much for your hard work!

Reply
0 Kudos
mark_chuman
Hot Shot
Hot Shot

Hate to hear that Romino Smiley Sad.  We currently do not have vDS implemented, but most likely will move to it in v6.  I'll take a look to see if that would be easy to do or not.

Reply
0 Kudos
snoopj
Enthusiast
Enthusiast

Quick question on the DVS side.  Before you remove the host from the 1st vCenter, are you disconnecting any physical NICs from the DVS before migrating?  I remember working on a script very similar to this (outside of many of the settings that I did not need to replicate exactly in the 2nd vCenter).

What I did was removed one of the physical NICs from the DVS in the 1st vCenter:

Get-VMHost -Name $vmhost.Name | Get-VMHostNetworkAdapter -Physical -Name vmnic0 | Remove-VDSwitchPhysicalNetworkAdapter -Confirm:$false

That way, I had one physical NIC that I could attach to the DVS in the new vCenter that was not associated with the old vCenter's DVS.  vmnic1 was still active for the VM connections and would continue to be when I disconnected the host from the 1st vCenter and added it to the second vCenter (don't know whether that's technically supported, per se, but it worked....it was like creating a scenario where vCenter was down...you rely on the local DVS information on the host to operate).

When I added the host into the second vCenter, I'd then add the host to the new DVS and then add vmnic0 to the new DVS:

$dvs = Get-VDSwitch $newDVS

foreach ($vmhost in $vmhosts)

{

     Add-VDSwitchVMHost -VDSwitch $dvs -VMHost $vmhost.Name -Confirm:$false

     $vmhostNA = Get-VMHost -Name $vmhost.Name | Get-VMHostNetworkAdapter -Physical -Name vmnic0

     $dvs | Add-VDSwitchPhysicalNetworkAdapter -VMHostNetworkAdapter $vmhostNA -Confirm:$false

}

After that, I was then able to start migrating VMs over to the new DVS portgroups (which I had created earlier), along with vmkernel ports.

If you haven't, I'd recommend disconnecting a physical NIC from the DVS (assuming redundant NICs) in the 1st vCenter, otherwise, you may have lingering DVS configuration issues that may be causing your message in question.

For the record, I did have to resort to this due to private VLANs.  Converting everything back to a standard vSwitch was going to knock too many live VMs offline to migrate.  Had to keep them up with minimal impact (maybe 1-2 pings missed for the VM when transitioning over from cached DVS info to 2nd vCenter's portgroup).

mark_chuman
Hot Shot
Hot Shot

We've continued to push vDS implementation year after year and have not yet implemented, so I actually don't deal with vDS within the script.  Most likely we'll be looking at it again for version 6, but that's a ways out for us.  My goal for version 6 is to completely automate VC builds and migrations, so we can just set schedules and be notified if something goes wrong during the script run - I could pretty much do that now with the migration piece as the script just cycles through a csv file for clusters to migrate.  Thinking of moving to a more advanced way of doing this by actually looking at two environments and migrate things to a certain location based on rules (ie, this region's VC handles these clusters etc..) *Sorry, just noticed you were responding to Romino - Smiley Happy

Reply
0 Kudos
snoopj
Enthusiast
Enthusiast

No worries.  I'm just trying to remember if I had seen his error before.  When I was testing all that out (oh, it's been about a year since I wrote that original migration script my old employer used to mass migrate clusters from large vCenters to individual data center room vCenters....went from 2 total vCenters to something like 10 individual vCenters).  I remember trying to do the initial testing without removing physical NICs from the DVS and I had nothing but problems since the local cached information was still tied to those physical NICs.  Removing just a single NIC and then add the host/physical NIC to the new vCenter and DVS rectified the issue.

I'm pretty sure it's not exactly a method that VMware support would approve of, but it works!

--j

Reply
0 Kudos
Romino
Contributor
Contributor

Thank you for the tip. I will try to proceed with removing the NIC first. Private VLANs are in place here as well. Would you be so kind and post your migration script here? Thank you!

Reply
0 Kudos
snoopj
Enthusiast
Enthusiast

Let me see what I can do with that script to sanitize it and post it.  I've been meaning to do so for quite sometime, but it keeps getting pushed back due to other efforts.  Smiley Happy

andjest
Contributor
Contributor

Hi Mark

I'm testing out the script in my lab before deploying it to migrate two clusters of three hosts each from vCenter 5.1u1 to vCSA 5.5

I've hit a snag just after it removes the hosts from the first cluster. The following error happens 13 times and none of the permissions are applied to the folders

Importing permissions for the folders, hosts, virtual machines, datacenter and cluster

Action to take for this exception:

Exception calling "SetEntityPermissions" with "2" argument(s): "The object or item referred to could not be found."

[C] Continue  [I] Silently Continue  [B] Break  [S] Suspend  [?] Help

(default is "C"):

Exception calling "SetEntityPermissions" with "2" argument(s): "The object or item referred to could not be found."

At C:\Move\vCenterMirationScript_2_6_2015\FROMCSV_vCenterMigration.ps1:579 char:3

+         $authMgr.SetEntityPermissions(($folder | Get-View).MoRef, $perm)

+         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException

    + FullyQualifiedErrorId : VimException

I've attached the perms_export_folders.csv

Folders are created correctly, and the VMs do move into the correct folders, but from the "Tasks and Events" screen it looks like the folders are being created twice

Reply
0 Kudos
mark_chuman
Hot Shot
Hot Shot

Hey andjest.

Three things the script does not handle well (or at all Smiley Happy)

1. Duplicate folder names (within the scope of a vCenter server).

2. Folder names that connect brackets < [ ] >

3. Folder names that are the same name as the datacenter they reside under.

You should have smooth sailing if you remove these three points of failure.  I haven't put much time into getting around these as I am trying to move in the direction of tags.  Folder imports and VM placements in those folders takes forever.  For example, we are seeing a cluster without folders take ~6 minutes to migrate and those with VMs in folders (100+ VMs) are taking 45+ minutes.  Just doesn't connect up with the vision I have for speeding everything thing up going forward.  Just rename the source folders you have to make them unique (ie, I just add the parent folder name - parentfoldername_childfoldername) to make them unique.

Reply
0 Kudos
andjest
Contributor
Contributor

I can confirm there are no duplicate folder names, no folder names that match the datacenter name, no folder names for my datastores that match anything

I do have resource pools that match folder names... Could that be causing it?

Reply
0 Kudos
mark_chuman
Hot Shot
Hot Shot

Can you confirm when the error hits?  From your post you say it takes place after the hosts are removed from the first cluster, but from the error, to me this should take place after the hosts are confirmed to have been connected.  This is where I am envisioning the error taking place?:

#Checking that the the hosts are connected before proceeding

foreach ($vmhost in $CSVhosts) {

  Do {

      $status = Get-VMHost -Name $vmhost.name | Select -ExpandProperty ConnectionState

      Write-Output "Connection state of $($vmhost.name) = $status - Process will proceed when host status is connected or maintenance mode"

      Start-Sleep -Seconds 1

  }

  While ($waitForThese -notcontains $status)

}

#Import of permissions

Write-Host "Importing" -ForegroundColor Green -NoNewline

Write-Host " permissions for the folders, hosts, virtual machines, datacenter and cluster

"

Start-Sleep -Seconds 1

#Import folder permissions.  Will be executed at operator's discretion.

#Note that the $folder value is narrowed down to the destinationcenter as a duplicate folder in another datacenter will cause an error.

$folderperms = Import-Csv "./$SourcevCenter/$Cluster./perms_export_folders.csv"

foreach ($fpm in $folderperms) {

  $svcgroup = $fpm.Principal

  $folder = Get-Datacenter $DestinationDatacenter | Get-Folder -Name $fpm.Entity

  $authMgr = Get-View AuthorizationManager

  $perm = New-Object VMware.Vim.Permission

  $perm.principal = $svcgroup

  $perm.group = if ($fpm.IsGroup -eq "TRUE") {$true} else {$null}

  $perm.propagate = if ($fpm.Propagate -eq "TRUE") {$true} else {$null}

  $perm.roleid = ($authMgr.RoleList | where{$_.Name -eq $fpm.Role}).RoleId

  $authMgr.SetEntityPermissions(($folder | Get-View).MoRef, $perm)

Reply
0 Kudos
mark_chuman
Hot Shot
Hot Shot

Hopefully it's this easy.  Can you make sure the roles exist in the new VC? - from the names, they look like custom adds.

warkaj
Contributor
Contributor

dVS is on our radar as well but with mismatched hosts and vswitch layouts I really don't want to run the risk of dumping production machines and being "that guy" who breaks critical business apps during working hours. Our change management process also prohibits a lot of production work during business hours which I'm sure most of you have as well.

I would like to test this script out as I am migrating from the vAPP vCenter 5.5 to Win-OS based vCenter 6. We just got so fed up with the vAPP version of vCenter that we are going back to the Win-OS ver.

Does this work for appliance -> windows based vcenters?

--- If you found this or any other answer helpful, please consider the use of the Helpful or Correct buttons to award points.
Reply
0 Kudos
mark_chuman
Hot Shot
Hot Shot

I've only used it to go from 5.1 to 5.5 (all windows based VCs), but I see no reason why going from an appliance hosted VC would matter as they both respond the same to PowerCLI actions (I think).  Test it out in the lab definitely, but I've used it to successfully migrate 2k+ hosts and 20k+ vms so far.  Let me know how it goes, but look out for the 3 gotchas - using duplicate folder names, using brackets in folder names and using the datacenter name in folder names.

Reply
0 Kudos
andjest
Contributor
Contributor

I can confirm that the error I was getting was due to missing the roles on the destination vCenter Server. Once I added them the script ran fine

Reply
0 Kudos
gtaylor1
Contributor
Contributor

Hi Mark,

Amazing script... I only had a few problems with it... the largest one was probably the way it handled the Annotations at the end:

Custom attributes and notes for MELMISVW02 (Glenn Win7 VDI) are being imported now...

Confirm

5/06/2015 3:09:16 PM Set-Annotation  Could not find annotation with name 'Availability'.

[Y] Yes  [A] Yes to All  [H] Halt Command  [S] Suspend  [?] Help (default is "Y"): a

Set-Annotation : 5/06/2015 3:09:16 PM    Set-Annotation        Could not find annotation with name 'Availability'.

At E:\scripts\vCenterMigrationUpdated\FROMCSV_vCenterMigration.ps1:684 char:4

+    Set-Annotation -Entity (get-vm $vm.Name) -CustomAttribute $vm.DR -Value $vm." ...

+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    + CategoryInfo          : InvalidData: (:) [Set-Annotation], ViError

    + FullyQualifiedErrorId : Client20_InventoryServiceImpl_SetAnnotationValue_AnnotationNotFound,VMware.VimAutomation.ViCore.Cmdlets.Commands.SetAn

   notation

Confirm

5/06/2015 3:09:33 PM Set-Annotation  Could not find annotation with name 'Backup Owner'.

[Y] Yes  [A] Yes to All  [H] Halt Command  [S] Suspend  [?] Help (default is "Y"): y

Any time it couldn't find an annotation value it would prompt me for this... Now there may be holes like this on all our VM's... I can't really sit there accepting the prompt for 350+ VM's.

The other two errors I faced were one during the folder creation and one during the permission configuration, but it doesn't appear to be anything major that I couldn't fix in a few seconds after the migration was complete... The annotations problem above is probably the biggest PITA.

Attached is my transcript.

Reply
0 Kudos
LucD
Leadership
Leadership

If you add the switch -Confirm:$false to the Set-Annotation cmdlet, you will not the prompts (provided that is what you want).


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos
gtaylor1
Contributor
Contributor

Actually looking through the annotations in my environment, there's annotations on probably only 3% of the VM's... What can I do to the script to skip the annotation copy entirely?

I presume it's as simple as commenting out the following:

#Begin custom attributes export

Write-Host "Exporting " -NoNewline

Write-Host "Custom Attributes" -ForegroundColor Green

Write-Host " "

$startdir = ".\$SourcevCenter\$Cluster\"

$exportfile = "$startdir\attributes_export_vm.csv"

$vms = Get-Cluster  $Cluster | Get-VM

$Report =@()

    foreach ($vm in $vms) {

        $row = "" | Select Name, Notes, DR, "DR Value", DRStorage, "DRStorage Value"

        $row.name = $vm.Name

        $row.Notes = $vm.Notes

        $customattribs = $vm | select -ExpandProperty CustomFields

        $row.DR = $customattribs[0].Key

        $row."DR Value" = $customattribs[0].value

        $row.DRStorage = $customattribs[1].Key

        $row."DRStorage Value" = $customattribs[1].value 

        $Report += $row

    }

$report | Export-Csv "$exportfile" -NoTypeInformation

#End custom attributes export

#Begin import of virtual machine custom attributes

Write-Host " "

Write-Host "Importing" -ForegroundColor Green -NoNewline

Write-Host " VM custom attributes"

Write-Host " "

$startdir = ".\$SourcevCenter\$Cluster\"

$importfile = "$startdir\attributes_export_vm.csv"

$NewAttributes = Import-Csv $importfile

ForEach ($vm in $NewAttributes){

        if(!$vm."DR Value" -and !$vm."DRSTorage Value") { } else {

   Write-Host "Custom " -NoNewline

   Write-Host "attributes" -ForegroundColor Green -NoNewLine

   Write-Host " and " -NoNewline

   Write-Host "notes" -ForegroundColor Green -NoNewLine

   Write-Host " for " -NoNewline

   Write-Host $vm.Name -ForegroundColor Green -NoNewLine

   Write-Host " are being imported now..."

   Set-Annotation -Entity (get-vm $vm.Name) -CustomAttribute $vm.DR -Value $vm."DR Value" -confirm:$false

   Set-Annotation -Entity (get-vm $vm.Name) -CustomAttribute $vm.DRStorage -Value $vm."DRStorage Value" -confirm:$false

   Write-Host " "

}

}

#End import of virtual machine custom attributes

Reply
0 Kudos
LucD
Leadership
Leadership

Without actually testing it, yes, that looks the parts handling the annotations.

In fact, you only need to comment out the import part.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos
mark_chuman
Hot Shot
Hot Shot

Let me take a deeper look at your transcript, but a couple options you have are to just comment out certain sections that you are having trouble with or adjust the error reporting for that section.  Example.

Commenting out:

pastedImage_0.png 

Adjusting error reporting for just a section:

pastedImage_1.png

On the folder errors make sure you are not getting hit by duplicates.  Folders were the bane of my existence with the script as we use them and notes/annotations extensively.  Caused the most problems and greatly slowed down the migration of the cluster.

Duplicate folder names that exist under the same vCenter - ie, the same folder name existing say in different datacenters under the same VC.

Reply
0 Kudos