VMware Cloud Community
Hetfield84
Enthusiast
Enthusiast
Jump to solution

Storing tags in variables

Hi,

I'm trying to assign each tag assigned to a VM to a separate variable. If I run the command below it'll store all of the tags in the $allTags variable:

$allTags = Get-VM "testVM" | Get-TagAssignment | Out-String

Lets say for example the VM "testVM" has three tag categories with tags assigned to each:

1. Tag category = Application; Tag = "SQL"

2. Tag category = OS; Tag = "Windows Server 2016"

3. Tag category = Backup; Tag ="Yes"

How would I store each tag into a unique variable? I've tried using the example below but it fails and I cant for the life of me figure this one out.

e.g. $appTag = $allTags.Tag.Application

1 Solution

Accepted Solutions
LucD
Leadership
Leadership
Jump to solution

Ok, in that case try something like this.
The sample is with only 3 categories, but you can expand the list.

$catNames = 'Cat1', 'Cat2', 'Cat3'

$cat = Get-TagCategory -Name $catNames


$obj = @{

   VM = ''

}

$catNames | ForEach-Object -Process {

   $obj.Add($_, '')

}


Get-VM |

ForEach-Object -Process {

   $present = $false

   $vmObj = $obj.Clone()

   $vmObj.VM = $_.Name

   Get-TagAssignment -Entity $_ -Category $cat |

   ForEach-Object -Process {

   $present = $true

   $vmObj[$_.Tag.Category.Name] = $_.Tag.Name

   }

   if ($present)

   {

   New-Object -TypeName PSObject -Property $vmObj

   }

} | Select -Property (@('VM') + $catNames) |

Export-Csv -Path .\report.csv -NoTypeInformation -UseCulture

---------------------------------------------------------------------------------------------------------

Was it helpful? Let us know by completing this short survey here.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

View solution in original post

11 Replies
LucD
Leadership
Leadership
Jump to solution

With the New-Variable cmdlet you can create variables.

Something like this for example

Get-VM -Name MyVM | Get-TagAssignment |

ForEach-Object -Process {

   New-Variable -Name "Tags-$($_.Entity)-$($_.Tag.Name)" -Value $_.Tag

}

Get-Variable -Name "Tags*"


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Hetfield84
Enthusiast
Enthusiast
Jump to solution

Thanks LucD.

I should’ve given you the full story, I’d then like to output all the tags assigned to a VM to a CSV file. The header of each field would be the tag category and the field value would be the tag.

I’ve tried playing around with what you provided below however I’m not sure how to extract the data from the Tags variable. Thoughts? Below are the results when I run your code that you provided.

Name Value

---- -----

Tags com.vmware.cis.tagging.TagAssociationModel.Tag.Name

Tags-RGTest2016-12345678 Support Case/12345678

Tags-RGTest2016-8/14/2019 Date Created/8/14/2019

Tags-RGTest2016-ITIS Owner/ITIS

Tags-RGTest2016-Microsoft W... OS/Microsoft Windows Server 2016 (64-bit)

Tags-RGTest2016-N Backup/N 

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

To export to a CSV, all the rows should have the same properties.

Properties can be empty.

How are these Tags assigned?

Is there one tag in a Category? Or can there be multiple tags in a Category?

Are the Categories a fixed set of Categories?


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Hetfield84
Enthusiast
Enthusiast
Jump to solution

Hey,

The categories are a fixed set, we have maybe 8 of them. There can be multiple tags to a category, but only one tag per category on a VM.

I hope this helps.

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

One more question, I assume you know the names of these 8 categories?

So they can hard-coded in the script?


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos
Hetfield84
Enthusiast
Enthusiast
Jump to solution

Hi,

Correct, I know the names of the categories and have no issues hard coding them into the script as the categories do not change very often.

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

Ok, in that case try something like this.
The sample is with only 3 categories, but you can expand the list.

$catNames = 'Cat1', 'Cat2', 'Cat3'

$cat = Get-TagCategory -Name $catNames


$obj = @{

   VM = ''

}

$catNames | ForEach-Object -Process {

   $obj.Add($_, '')

}


Get-VM |

ForEach-Object -Process {

   $present = $false

   $vmObj = $obj.Clone()

   $vmObj.VM = $_.Name

   Get-TagAssignment -Entity $_ -Category $cat |

   ForEach-Object -Process {

   $present = $true

   $vmObj[$_.Tag.Category.Name] = $_.Tag.Name

   }

   if ($present)

   {

   New-Object -TypeName PSObject -Property $vmObj

   }

} | Select -Property (@('VM') + $catNames) |

Export-Csv -Path .\report.csv -NoTypeInformation -UseCulture

---------------------------------------------------------------------------------------------------------

Was it helpful? Let us know by completing this short survey here.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Hetfield84
Enthusiast
Enthusiast
Jump to solution

Thank you! I took what you provided and slightly modified it, I removed the error handling part too where it checks to see if there are tags in that category. I did this because I was getting an error stating:

"Index operation failed; the array index evaluated to null.

At D:\Scripts\getVMTagsOnHost\getVMTagsOnHost.ps1:28 char:9

+         $vmObj[$_.Tag.Category.Name] = $_.Tag.Name

+         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    + CategoryInfo          : InvalidOperation: (:) [], RuntimeException

    + FullyQualifiedErrorId : NullArrayIndex

Index operation failed; the array index evaluated to null."

I figured out it threw these errors up if a VM didn't have a tag in the category it was processing. I'll play around with the error handling but this is not a production script so I'm not too concerned about it. Below is what my script looks like in full, and works like a charm. It's also MUCH faster than the way I was doing it previously, which was to do a Get-VM | Get-TagAssignment for each category for each VM.

$hst = Read-Host "Enter the ESXi Host FQDN name"

$catNames = 'Owner', 'Application', 'OS', 'Created By', 'Support Case', 'Date Created', 'Backup', 'Virtual Appliance'

$cat = Get-TagCategory -Name $catNames

$obj = @{

   VM = ''

}

$catNames | ForEach-Object -Process {

   $obj.Add($_, '')

}

Get-VMHost -Name $hst | Get-VM | ForEach-Object -Process {

    $vmObj = $obj.Clone()

    $vmObj.VM = $_.Name

    Get-TagAssignment -Entity $_ -Category $cat | ForEach-Object -Process {

        $vmObj[$_.Tag.Category.Name] = $_.Tag.Name

    }

    New-Object -TypeName PSObject -Property $vmObj

} | Select -Property (@('VM') + $catNames) | Export-Csv -Path ".\VM tags on $hst.csv" -NoTypeInformation -UseCulture

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

Can you try adding the ErrorAction parameter?

Get-TagAssignment -Entity $_ -Category $cat -ErrorAction SlientlyContinue


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos
Hetfield84
Enthusiast
Enthusiast
Jump to solution

Hey,

I gave it a shot and still get the error:

Get-TagAssignment -Entity $_ -Category $cat -ErrorAction SilentlyContinue | ForEach-Object -Process {

        $vmObj[$_.Tag.Category.Name] = $_.Tag.Name

    }

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

Does the VM for which you get the error, has no Tags, in any Category, at all?
I can't seem to be able to replicate that error when a VM doesn't have a Tag in a specific Category.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos