Migrate folder structure from old to new vSphere vCenter

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.

3 thoughts on “Migrate folder structure from old to new vSphere vCenter”

Leave a Reply

Your email address will not be published. Required fields are marked *