powershellpowercli

PowerCLI Get VM Tag Assignment with the results broken into custom columns


I am new to working with PowerCLI and need to pull all the Tag Assignments from the VMs. Getting this information is relatively simple, but controlling the output into a format I need it to be is proving rather difficult.

here is the code I am working with.

Get-VM | Get-TagAssignment | select entity, Tag | sort Entity | format-table -AutoSize

the output is pretty easy to understand and looks like the table below.

Entity Tag
Server1 VM:TagCategory1/Content1
Server1 VM:TagCategory2/Content2
Server1 VM:TagCategory3/Content3
Server1 VM:TagCategory4/Content4
Server1 VM:TagCategory5/Content5
Server2 VM:TagCategory2/Content2
Server2 VM:TagCategory3/Content3
Server2 VM:TagCategory1/Content1
Server2 VM:TagCategory4/Content4
Server2 VM:TagCategory5/Content5
Server3 VM:TagCategory2/Content2
Server3 VM:TagCategory3/Content3
Server3 VM:TagCategory1/Content1
Server3 VM:TagCategory4/Content4
Server3 VM:TagCategory5/Content5
Server3 VM:TagCategory2/Content2
Server3 VM:TagCategory3/Content3
Server3 VM:TagCategory1/Content1
Server3 VM:TagCategory4/Content4
Server3 VM:TagCategory5/Content5
Server4 VM:TagCategory2/Content2
Server4 VM:TagCategory3/Content3
Server4 VM:TagCategory1/Content1
Server4 VM:TagCategory4/Content4
Server4 VM:TagCategory5/Content5

As you can see, it duplicates the server name and lines it up with the Tag information. It is sorted by Entity so the Tag info can appear out of order. some of the servers have multiple Tags for the same Tag Category as seen in the Server 3 example above. What I am trying to do is to remove the duplicate Server names and create custom columns for the tag output.

Entity VM:TagCategory1 VM:TagCategory2 VM:TagCategory3 VM:TagCategory4 VM:TagCategory5
Server1 Content1 Content2 Content3 Content4 Content5
Server2 Content1 Content2 Content3 Content4 Content5
Server3 Content1 Content2 Content3 Content4 Content5
Content1 Content2 Content3 Content4 Content5
Server4 Content1 Content2 Content3 Content4 Content5

Creating custom tables with custom formats in PowerShell/PowerCLI is a problem for me and really need some help with this one.

Thank you in advance for any help and suggestions.


Solution

  • Use the Group-Object cmdlet to group objects together by a common property expression:

    # prepare a collection of property/column names
    $propertyNames = @('Entity')
    
    # group tag records by entity
    $tagsGroupedByEntity = Get-VM |Get-TagAssignment |Select Entity, Tag |Group-Object Entity
    
    $results = $tagsGroupedByEntity |ForEach-Object {
      # create a table of properties for the result object for each group
      $resultRecord = [ordered]@{ Entity = $_.Name }
      foreach ($tagRecord in $_.Group) {
        # split category and content apart 
        $category, $content = $tagRecord.Tag -split '/',2
        # update result object table with tag contents
        $resultRecord[$category] = $content
        # add any previously-unseen category name to the list of property names
        if ($category -notin $propertyNames) {
          $propertyNames += $category
        }
      }
    
      # create and output result object
      [pscustomobject]$resultRecord
    }
    
    # use property name list to ensure all the objects have the same shape
    $results |Select-Object -Property $propertyNames