Sometimes I find it easier to create a new vCenter server then migrate the old one, and it is a perfectly good solution in many cases.
But annoyingly there is a lot of manual work involved.
One problem is the VM’s and Templates folders. They do not follow the host, so you have to create the folder structure manually and move each VM into the correct folder. Well I am way to lazy to do that by hand, so it’s time to Automate!
The following powershell code was created and testet in vSphere PowerCLI 6.5.1. Everything here is used at your own risk. I do not recommend that you use it through copy paste. Please read and understand the code before you execute.
Any suggestions or alterations are most welcome. This code should not be consider done or production ready. It was something I created in 1 hour to solve an ad-hoc problem.
Prerequisites
Before running the code you have installed and configured you new vCenter. You have disconnected your hosts from the old vCenter, but not removed anything from it. So the status on the old vCenter is that VMs and Hosts are disconnected.
You have connected your hosts to the new vCenter, and migrated any switches and VM networking. All hosts and VMs are connected to your vCenter, and they are located in the root folder or in Discovered VMs.
You should be good to go. Good Luck!
The Code
Connect-VIServer "<Source vCenter Name>" Connect-VIServer "<Target vCenter Name>" $sourceDatacenterName = "<Name of your source Datacenter>" $targetDatacenterName = "<Name of your target Datacenter>" $moveVms = $true # Should VMs in target vCenter be moved to folders by Name best effort # Checks if folder already exists Function Check-Folder($f, $t) { $result = $true Try { Get-Folder -Location $t -Name $f.Name -ErrorAction Stop #Write-Host "Folder Found" $result = $true } Catch { #Write-Host "Folder does not exist" $result = $false } return $result } # Creates the folder and moves the VMs Function Create-Folder($f, $t, $move, $targetRoot) { if (Check-Folder -f $f -t $t) { Write-Host "!!!Folder already exists: " $f.Name } else { Write-Host "Creating Folder: " $f.Name $targetFolder = New-Folder -Name $f.name -Location $t if ($moveVms) { #Write-Host "Moving VMs" $VMs = Get-VM -Location $f -NoRecursion foreach ($vm in $VMs) { Write-Host "Moving VM:" $VM.Name Try { $targetVM = Get-VM -Name $vm.name -Location $targetRoot -ErrorAction Stop if ($targetVM.Length -gt 1) { Write-Host "Multiple VMs Error" throw("Multiple VMs found") } else { Write-Host "Found VM:" $targetVM.name $moveJob = Move-VM $targetVM -Location $targetFolder } } Catch { Write-Host "Could not find VM:" $vm.name } } } Create-SubFolders -f $f -t $targetFolder -move $move -targetRoot $targetRoot } } # Cycles through subfolders and creates them Function Create-SubFolders($f, $t, $move, $targetRoot) { $subFolders = Get-Folder -Location $f foreach ($folder in $subFolders) { Create-Folder -f $folder -t $t -move $move -targetRoot $targetRoot } } # MAIN $sourceLocation = Get-folder -Name vm | Where-Object { $_.Parent -Like $sourceDatacenterName } $targetLocation = Get-folder -Name vm | Where-Object { $_.Parent -Like $targetDatacenterName } $allRootFolders = Get-Folder | Where-Object { $_.Parent -Like "vm" } $sourceRootFolders = $allRootFolders | Where-Object { $_.Parent -eq $sourceLocation } # Goes through all root folders in sourceDatacenter foreach ($folder in $sourceRootFolders) { # Create Root Folders if (Check-Folder -f $folder -t $targetLocation) { Write-Host "Folder already exists: " $folder.Name } else { #Write-Host "Creating Folder: " $folder.Name Create-Folder -f $folder -t $targetLocation -move $moveVms -targetRoot $targetLocation } }
Notes
Please note that this code will only create folders and move VMs if the folder does not already exist in the target vCenter Datacenter. It will also move the VM multiple times, since I am finding the VMs in folder recursive. This is because many VMs end up in the Discovered VMs Folder, and I was ok with this happening, so I did not bother finding a better solution.
If you old and new datacenters have the same name, you can just find the object for them i another way at the top of the script. Or you can alter the names temporarily.
Please leave any suggestions or comments below.
Great Script
This script is amazing. Worked perfectly for helping me migrate from a 5.5 cluster to 6.5U1D
🙂