So recently i have been working on a customer engagement to automate the migration of thier ESXi hosts between vCenters, with no downtime to the VMs running on the hosts. There are plenty of blog posts on the internet on how to do this and I won’t post my completed script (over 1500 lines of gross-ness) however one tricky problem I came across was how to migrate the vCenter tag assignments across with the VMs and other inventory objects.
I found the following blog post which details two functions that can be used to Export and Import the Tag Category, Tag Name and Tag Assignment, however the assignment component is only valid when exporting and importing to the same vCenter instance.
In my case I am actually moving the ESXi hosts to a a completely different vCenter, which in effect changes the MORef of the VMs and other objects. This basically breaks the import location function for the tags, as this function relies on the MORef to be the same.
To get around this I updated the foreach loop in the original Import-Tag function found as below:
- Use the ExtensionData propery of the exported tag data to determine the object type of the object that is having the tag assigned.
- Split the returned string to grab only the type info that we need.
- Create a new vSphere View object using the Object Type extracted from the above property, and filtering based on the entity name.
- Create the new Tag-Assignment with the vSphere View object created above.
Updated code for the assignment foreach loop is below (for the original Function details see the linked blog post above):
foreach ($assignment in $assignList) { # Type is going to be the the 3rd string seperated by '.' in the ExtensionData value $typeString = $assignment.Entity.ExtensionData $typeString = $typeString.split('.',3) Try { $assignTag = (Get-Tag -Server $server -Name $assignment.Tag.Name) $tempView = Get-View -Server $server -ViewType $typeString[2] -Filter @{"Name"=($assignment.Entity.Name)} $assignEntity = Get-VIObjectByVIView $tempView New-TagAssignment ` -Tag $assignTag ` -Entity $assignEntity ` -Server $server } Catch { Write-Host "Error assigning tag '$($assignTag.Name)' to '$($assignment.Entity.Name)', already exists?. Skipping." }
Now obviously the above code assumes that the object having its tag assigned has a unique name in vCenter, which may not be the case in your environment, so make sure you test!