Automating Tags and Tag Category creation and assignment with PowerCLI

Fimageor a couple of releases now PowerCLI has been able to work with vSphere Tags, A tag is a label that you can apply to objects in the vSphere inventory.

After creating a tag, you can assign that tag to a category. Categories allow you to group related tags together. When you define a category, you can also specify the type of objects to which its tags can be applied to and whether more than one tag in the category can be applied to an object.

For example, if you want to tag your virtual machines by the owner, you can create a category called “Owner” and specify that it applies to virtual machines only and that only a single tag can be applied to a virtual machine at any time. The tags in this category could be Alan, John or Fred etc.

I have had a few people ask me how they can use PowerCLI to work with external systems, CMDBs, databases or even just a CSV file.

One example of this is where a company could have various information about hosts or datastores or virtual machines, like the project that purchased these, a cost code or an owner.  This data is generally stored somewhere else but it would be great to see this information straight in the vSphere Web Client where you manage the objects so that you can instantly contact the owner or work out which project the object is being used for etc.

The below video shows how we can use PowerCLI and this generic script I created to import the data, create the tags and tag categories and assign them to the machines, it uses a csv as input but this could obviously be changed to anything which can be read in PowerShell, like a API, database, application etc etc.

Automating tags and tag categories video

Example Script

This script is the script I created as an example which relates each of the items in the Name column to an object in the inventory then for each of the other column headers it will create a category and then the tags that are under the categories, once this has been done it will apply the tags to the objects in the Name column.

Connect-viserver myvc.corp.local -user administrator@vsphere.local -pass Pa$$w0rd
$CMDBInfo = Import-CSV C:\Software\cmdbinfo.csv

# Get the header names to use as tag category names
$TagCatNames = $cmdbinfo | Get-Member | Where {$_.MemberType -eq "NoteProperty"} | Select -Expand Name

# Create the Tag Category if it doesnt exist
Foreach ($Name in ($TagCatNames | Where {$_ -ne "Name"})) {
    if (-Not (Get-TagCategory $Name -ea SilentlyContinue)) {
        Write-Host "Creating Tag Category $Name"
        New-TagCategory -Name $Name -Description "$Name from CMDB" | Out-Null
        
        # Create Tags under the Tag Categories
        $UniqueTags = $cmdbinfo | Select -expand $name | Get-Unique
        Foreach ($Tag in $UniqueTags) {
            if (-Not (Get-Tag $Tag -ea SilentlyContinue)) {
                Write-Host "..Creating Tag under $Name of $Tag"
                New-Tag -Name $Tag -Category $name -Description "$Tag from CMDB" | Out-Null
            }
            # Assign the Tags to the VMs/Hosts
            $cmdbinfo | Where {$_.($Name) -eq $Tag} | Foreach {
                Write-Host ".... Assigning $Tag in Category of $Name to $($_.Name)"
                $TagAssignment = Get-Tag -Category $Name -name $Tag
                New-TagAssignment -entity $($_.Name) -Tag $Tagassignment | Out-Null
            }
        }          
    }
}

15 thoughts on “Automating Tags and Tag Category creation and assignment with PowerCLI

  1. Mike

    brilliant as always! I notice that this appears to be a one-time process. For example if I take VM1 and place a tag/category onto it via script, I can’t go back and add VM2 to the same tag, it will just ignore it and not do anything. Is there a way to check for existing tags/categories and use them if exist?

  2. Christian Z

    You can avoid the loop using:
    $UniqueTags = $cmdbinfo | Select -expand $name | Sort-Object -Unique

  3. Bobby

    $CMDBInfo = Import-CSV C:\Temp\cmdbinfo.csv

    # Get the header names to use as tag category names
    $TagCatNames = $cmdbinfo | Get-Member | Where {$_.MemberType -eq “NoteProperty”} | Select -Expand Name

    # Create the Tag Category if it doesnt exist
    Foreach ($Name in ($TagCatNames | Where {$_ -ne “Name”})) {
    if (-Not (Get-TagCategory $Name -ea SilentlyContinue)) {
    Write-Host “Creating Tag Category $Name”
    New-TagCategory -Name $Name -Description “$Name from CMDB” | Out-Null

    # Create Tags under the Tag Categories
    $UniqueTags = $cmdbinfo | Select -expand $name | Get-Unique
    Foreach ($Tag in $UniqueTags) {
    if (-Not (Get-Tag $Tag -ea SilentlyContinue)) {
    Write-Host “..Creating Tag under $Name of $Tag”
    New-Tag -Name $Tag -Category $name -Description “$Tag from CMDB” | Out-Null
    }
    # Assign the Tags to the VMs/Hosts
    $cmdbinfo | Where {$_.($Name) -eq $Tag} | Foreach {
    Write-Host “…. Assigning $Tag in Category of $Name to $($_.Name)”
    $TagAssignment = Get-Tag -Category $Name -name $Tag
    New-TagAssignment -entity $($_.Name) -Tag $Tagassignment | Out-Null
    }
    }
    }
    }

  4. Bobby

    Hi Al,
    I was trying to get infront of the line but hopefully I could.
    I have been using your script to automate creating Tags to all our VMs. Unfortunately, it doesn’t seem to be creating “ALL” of my tags that are in my CSV file. I am actually not sure if it were creating anything because what I see are basically something close to my naming but it has the right information showing.
    CSV file layout:
    Name VMToolsVersion Priority_Level Startup_Sequence Cluster_rule(s) Cluster Operating_System Provisioned_MB In_Use_MB Cylance_Agent_Version Cylance_AQT Cylance_Mem_Protection
    Server1 T4 Management SUSE Linux Enterprise 11 (64-bit) 725685 328153

    VIEWED in WEB CLIENT:
    Assigned Tag Category Description
    Prod Cluster Prod from CMDB
    T4 Priority Level DR Priority Level
    Windows Server 2008 R2 – x64 OS Server 2008 R2 – 64 Based

    It shows information that are not specific to what i have on the CSV.
    Is it because that there could be same info existing tags ? If so then why did it not create a new tag with same information? Also the other column name which should have been created as tags did not get created. How is that? If so, can you assist on a script to wipe out all tags and recreate all tags that are specifically from the CSV?
    If you could please assist that would be greatly appreciated.

    Thank you so much.

    Bobby

  5. Shaikh

    Hi all,
    i have been asked to tag all our VM in side our three vCenters. i already have compile the csv file with columns heading with Name of the server, Department , Owner , Severity and Application, i am not good in powershell, can you please help me where do i need to make changes in this above script? please help me .
    Thanks.

  6. Travis VH

    For others out there that are trying to use this with a large import, the Get-Unique function only works on sorted lists. So if your “Categories” are not sorted the import will get stuck in a loop

  7. Dan

    Hi Al. Have you ever come across any issues running the Get-TagCategory cmdlets remotely (in my case via vRO)? I’m running PowerCLI 6.3 Release 1 against vCenter 5.5, and have a script on a remote PS host that is failing at the Get-TagCategory step – with an output of ‘null’. All other cmds (Get-VM etc) work without issue.
    Cheers,
    Dan

  8. Pingback: Fun with vSphere Tags | Virtual Chris

  9. Brian Lev-Ari

    This is really great material, my question is if you have the same script to export from the vCenter to the Excel file. The the VC DB can be the master, and it would be nice to export –> update –> and then import again.

    Thank,

    Brian

  10. greyhame79

    I am currently in the process of trying to organize a Vsphere/Vcenter such that we can determine via tag which tech in the department is responsible for a server and what SLA it is. We would like to see this information at a glance in the tags of each VM. However there are 350 VM’s so tagging them one at a time is going to be hard to track and time consuming. The VMs are currently organized into a VM Folder structure that looks like this (Production\Cisco\Unify\… the VM contained)

    My question is this. How can I get Tags made on VM folders to propagate down to the child folders and objects within that folder. For example I would like all the VMs in all the folders of the primary category “Production” to inherit the tag “Production Level Server” that is already setup on the Folder “Production”.

    Thus far this is not happening. If I place VM’s objects in a tagged folder they will inherit the tag but folders underneath will not.

    Is there a way to do this?

  11. Pingback: [VMware] news + interesting reads from the blogosphere: 01 Dec. 2014

  12. Pingback: [VMware] news + interesting reads from the blogosphere: 25 Nov. 2014

  13. Grzegorz

    Is there any possibility to use vSphere tags within vCenter Orchestrator workflows without actually using PowerCLI? If not then are there any plans to make it available from within vCenter Orchestrator? I’m not sure how many people are using them, but in our environment it would make things so much easier.

Leave a Reply to Grzegorz

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

This site uses Akismet to reduce spam. Learn how your comment data is processed.