VMware Cloud Community
MattHumphreys
Contributor
Contributor
Jump to solution

Get VM List based on Multiple Tags

I am trying to get a script to extract a list of virtual machines that have a particular tag combination from available tags and its proving to be quite difficult.

I have been creating a selection of tags based on using Get-Tags and out-gridview to allow the person executing it to decide on what tags they want to filter against.

My problem comes when I am trying to translate that selection into a filter to get a list of VM's with those tags, it could be a varying number of tags in the selection which I wont always know.

I also have the problem of trying to make a list of the vms that match all the tags together.

I have tried putting them into an array and then calling the tags from the position in the array:

Get-VM | Where-Object{(Get-TagAssignment -Entity $_ ).Tag.Name -Match $tag_checks[0].tag_name -and $tag_checks[1].tag_name}

that works but because the array can be any number of tags long that is my issue I dont know how to "create" enough entries for all the items in the array.

I have also looked at defining individual variables for each tag:

$t1 = Get-Tag -Name Name1
$t2 = Get-Tag -Name Name2

$tag1 = Get-VM -Tag $t1
$tag2 = Get-VM -Tag $t2

$results = $tag1 | ?{$tag2 -contains $_}

While both get me to the end result I am struggling to make it efficient and repeatable for a large list of VM's

I suspect I have hit a limitation in my programming knowledge, any advice welcomed

Reply
0 Kudos
1 Solution

Accepted Solutions
LucD
Leadership
Leadership
Jump to solution

Try something like this.
The variable $tagNames can contain 1 or more Tag names.

$tagNames = 'Tag1','Tag2','Tag3'

$vms = Get-VM -Tag $tagNames

$tagNames | ForEach-Object -Process {
  $vms = Get-VM -Tag $_ | where{$vms.Name -contains $_.Name}
}
$vms


How you populate the variable $tagNames is up to you. 


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

View solution in original post

4 Replies
LucD
Leadership
Leadership
Jump to solution

Try something like this.
The variable $tagNames can contain 1 or more Tag names.

$tagNames = 'Tag1','Tag2','Tag3'

$vms = Get-VM -Tag $tagNames

$tagNames | ForEach-Object -Process {
  $vms = Get-VM -Tag $_ | where{$vms.Name -contains $_.Name}
}
$vms


How you populate the variable $tagNames is up to you. 


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

MattHumphreys
Contributor
Contributor
Jump to solution

Thanks for that LucD, that gives me a list of VM's that matches any of the tags in $tagnames, I am looking to get to a list that contains only the VM's that match all of the tags, I have reluctantly come to the conclusion just for expediency that I will have to manually enter the tag information:

 

Get-VM | Select Name,@{Name="Tags";Expression={(Get-TagAssignment -Entity $_).Tag.Name}} |
Where {$_.Tags -match "Tag1" -and $_.Tags -match "Tag2" -and $_.Tags -match "Tag3" -and $_.Tags -notmatch "Tag4"} |
Format-Table -Autosize

 

It gives me the response I wanted and allows me to do things like exclude based on a particular tag or with a tag combination.

 

The reason for the whole thing is we are using veeam and tag combinations to group machines into backups but veeam doesnt easily display a list of VM's that are captured by the tag combination so I am doing this to get me a list to ensure that everything is correct before the backups run.

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

Did you try my latest reply?
That gives me only the VMs that have all the specified tags


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

Reply
0 Kudos
MattHumphreys
Contributor
Contributor
Jump to solution

Yes I have tried it just now and it works as you mentioned, gives me a list of the VM's that match all the specified tags and I have populated it from the list of available tags on the cluster.

I also added a limit on the Get-VM's to put it into a limited location so I dont search an entire vcenter just a specific datacenter

 

$location = Get-Datacenter | Out-GridView -Title "Select single location to run checks on" -OutputMode Single

$vms = Get-VM -Location $location -Tag $tagNames

$tagNames | ForEach-Object -Process {
  $vms = Get-VM -Location $location -Tag $_ | where{$vms.Name -contains $_.Name}
}
$vms.Name | Sort-Object |Format-Table -Autosize
Reply
0 Kudos