I'm looking for a way to find all VM's that have multiple tags assigned. For the sake of the question let's assume the tags are Alpha and Beta. The command that I've come up with works but it's very slow.
get-vm -tag alpha | Where{$_.PowerState -eq 'PoweredOn' and (Get-TagAssignment -Entity $_ ).Tag -match 'Beta'}
If I run the following, it's faster but I get VM's with either or.
get-vm -tag alpha,beta
It's only when I add the additional filter (Get-TagAssignment) to only show the second tag where it slows down. Is there a way to specify both tags in the quicker command but only return when both are found?
I would try something like this.
It avoids the Get-TagAssignment, which is an 'expensive' cmdlet.
$t2 = Get-Tag -Name Tag2
$vm1 = Get-VM -Tag $t1
$vm2 = Get-VM -Tag $t2
$vm1 | where {$vm2.Name -contains $_.Name}
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Which PowerCLI version are you using?
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Looks like 11.1
Here's a script I wrote that we use to loop thru our vCenters (12 of them) and dump nightly. It doesn't matter how long it takes since I'm sleeping 😉
I hope this helps.
$file = $null
$report = @()
foreach ($VCSvr in $vCSrvLst) {
## Connect to vCenter
Connect-viserver "$VCSvr.Corp.Realpage.com"
$report = @()
$TagCats = Get-TagCategory
# Loop through each row in Input and Search for VM and Get Creation Info
ForEach ($TCat in $TagCats) {
$TCatName = $TCat
write-host Exporting list of VMs assigned to Tag Category: $TCatName
$AssignedTags = Get-TagAssignment -Category $TCatName -ErrorAction SilentlyContinue
ForEach ($ATag in $AssignedTags) {
$row = "" | select VMName, Tag
$row.VMName = $ATag.Entity.Name
$row.Tag = $ATag.Tag
$report += $row
}
}
$report | sort -property @{Expression="VMName";Descending=$false} | Export-Csv TaggedVMs_$VCSvr.csv -NoTypeInformation
Disconnect-VIServer -Server * -Force:$true -Confirm:$false
}
That's the latest version, so your good.
There have been multiple reports about the slowness and even timeouts with the Get-TagAssignment.
You might want to give it a try with Kyle's module VMware.Community.CISTag.
Measurements showed that the cmdlets in that module are way faster.
There is a blog post, see New Community Module for Tag Management
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Thanks Ryan - This is mainly used when I need to apply snapshots to a group of VM's (like all Production VM's for X Application) so I'm not sure the script would be useful for this case. But I do like to see and dissect what others create!
Thanks LucD.
I will check out that module. So my question is, am I doing the query the right way? Or is there a way to specify multiple tags requiring both using just the -Tag parameter?
I would try something like this.
It avoids the Get-TagAssignment, which is an 'expensive' cmdlet.
$t2 = Get-Tag -Name Tag2
$vm1 = Get-VM -Tag $t1
$vm2 = Get-VM -Tag $t2
$vm1 | where {$vm2.Name -contains $_.Name}
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
That's really cool LucD. I like that response. Yes describing Get-TagAssignment as 'expensive' is a good description. The solution is no longer a one liner but it'll work when I incorporate it into a script. Thanks for this.