Backup/restore vCenter tags and tag assignments

Tags were introduced in vSphere 5.5, they are very versatile and are gaining more and more adoption. Because of this, resetting the Inventory Service database is becoming more and more problematic.
Remember, whenever you reset the Inventory Service database, you lose all tags.

I tested this in my lab : I reset the Inventory Service DB using my Powershell Script : Reset-ISDatabase .

Then, I checked back in the Web Client, and indeed, the tags, tag categories and tag assignments (which vCenter objects the tags are associated to) are all gone :

Tags are deleted

So, we need a solution to backup tags, categories and tag assignments to be able to restore them if we lose them all.
This script is great but it doesn’t take into account the tag assignments (it’s not its purpose).

For the sake of reference, here is the current state of the tags, categories and assignments in my test environment:

Tags and Assignments

Now, let’s see how we can export this information.

$TagCategories = Get-TagCategory
$Tags = Get-Tag
$TagAssignments = Get-TagAssignment

# Grouping the tag categories, the tags and the tag assignments into an array
$ExportArray = @($TagCategories,$Tags,$TagAssignments)

Export-Clixml -InputObject $ExportArray -Path Exported.xml

We group the tag categories, tags and tag assignments into an array because even though the cmdlet Export-Clixml seems to take multiple objects without complaining, according to Get-Help, it is supposed to only take one input object at a time.

We chose to export these objects to XML, rather than CSV because XML format is better suited for complex objects : objects with multi-valued properties or properties containing nested properties.

Now, let’s see how to use this XML file to restore all the categories, tags and assignments :

We import the data from the XML file back into PowerShell objects, like so :

$Import = Import-Clixml -Path Exported.xml

Remember it is an array, so we need to access the first element in the array to get the categories, the second element to get the tags and the third element to get the assignments.
For example, here is how to get the categories :

$Import[0] | fl *


Description : 
Cardinality : Single
EntityType  : {Datastore, DatastoreCluster}
Id          : InventoryServiceCategory-5ec0a856-78a4-4c3c-afb3-1c7d62b92537
Name        : Storage
Uid         : /VIServer=administrator@192.168.1.10:443/TagCategory=InventoryServiceCategory-5ec0a856-78a4-4c3c-afb3-1c7d62b92537/
Client      : VMware.VimAutomation.ViCore.Impl.V1.VimClient

Description : 
Cardinality : Single
EntityType  : {VApp, VirtualMachine}
Id          : InventoryServiceCategory-39c5fc34-4d8c-441a-b991-cd18390753b5
Name        : Business Impact
Uid         : /VIServer=administrator@192.168.1.10:443/TagCategory=InventoryServiceCategory-39c5fc34-4d8c-441a-b991-cd18390753b5/
Client      : VMware.VimAutomation.ViCore.Impl.V1.VimClient

So, here is how to create the categories from the imported XML data :

Foreach ( $category in $Import[0] ) {

    New-TagCategory -Name $category.Name -Description $category.Description `
    -Cardinality $category.Cardinality -EntityType $category.EntityType
}

To re-create the tags, we use the same technique :

Foreach ( $tag in $Import[1] ) {

    New-Tag -Name $tag.Name -Category (Get-TagCategory -Name $tag.Category) `
    -Description $tag.Description
}

We have to use Get-TagCategory -Name $tag.Category to convert the value of $tag.Category back to an object of the type : “VMware.VimAutomation.ViCore.Types.V1.Tagging.TagCategory”.
Why ? Because the parameter -Category of New-Tag can only take a value of that type (Get-Help New-Tag can confirm that) and the specific type for this value was lost during the export to XML.

Now, let’s restore the tags assignments :

Foreach ( $assignment in $Import[2] ) {

    $AssignTag = (Get-Tag -Name $assignment.Tag.Name)
    $AssignEntity = Get-VIObjectByVIView -MORef ($assignment.Entity.Id)

    New-TagAssignment -Tag $AssignTag -Entity $AssignEntity
}

The tricky part here is the $AssignEntity. The parameter -Entity of the cmdlet New-TagAssignment expects a VIObject, which could be a VM, a host, a datastore … any kind of vCenter object and our imported data represents the entity Id (aka MORef) as a string :

PS C:\> $Import[2].Entity.Id

Datastore-datastore-26
VirtualMachine-vm-62
StoragePod-group-p64

So we need to convert that back to the original VIObjects and that’s what Get-VIObjectByVIView allows us to do with the parameter -MORef.

Now, we have the same tags, categories and assignments as before but they have new UIDs so from vCenter point of view, they are different objects. This might have an impact on other sofware relying on vCenter tags, like vCloud Director for example. So, as always, test this in a lab before messing with your production environment !

Based on that, I made 2 functions Export-TagAndAssignment and Import-TagAndAssignment, which I packaged in a nice little module called vCenterTagging.psm1.
The module is available here.

Leave a Reply

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