I'm trying to speed up a script that gathers various tags and custom attributes. I managed to gather all tags into separate arrays which sped up the process significantly, Now, I want to do the same thing for custom attributes. With over 5,000 VM's, running Get-Annotation -Entity $Vm takes quite a while from start to finish. I only recently learned that the CustomFields are a part of the Get-VM results.
What I'd like to know, is how can I use the data that's already available?
# Get VM Info
$VMs = (Get-VM).where{$_.PowerState -eq 'PoweredOn' -or $_.PowerState -eq 'Suspended'}
foreach ($VM in $VMs) {
for ($i = 0; $i -lt $VMs.count; $i++){
if ($VMs[$i].Name -eq $VM) {
<magic here>
}
}
}
Viewing $VMs[0] |Select CustomFields shows each custom attribute, but I can't figure out how to get the values based on the name for each VM. I want to get the values for custom attributes "VM Owner" and "Application", for example.
Any assistance is appreciated. Thanks!
The CustomFields property is Dictionary, so you can use the Item method.
Something like this (watch out the key is case-sensitive)
(Get-VM).where{$_.PowerState -eq 'PoweredOn' -or $_.PowerState -eq 'Suspended'} |
Select Name,
@{N='VM Owner';E={$_.CustomFields.Item('VM Owner')}},
@{N='Application';E={$_.CustomFields.Item('Application')}}
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
The CustomFields property is Dictionary, so you can use the Item method.
Something like this (watch out the key is case-sensitive)
(Get-VM).where{$_.PowerState -eq 'PoweredOn' -or $_.PowerState -eq 'Suspended'} |
Select Name,
@{N='VM Owner';E={$_.CustomFields.Item('VM Owner')}},
@{N='Application';E={$_.CustomFields.Item('Application')}}
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Awesome! I will try this out and let you know. Also, if there's any way I can speed up the tag gathering, I'd appreciate your input.
# Same Get-VM as above, followed by...
$EnvironmentTagList = Get-TagAssignment -Entity $VMs -Category "Environment"
for ($i = 0; $i -lt $VMs.count; $i++) {
$VM = $VMs[$i]
Write-Progress -Activity "Getting metadata..." -status "Checking $VM..." -percentComplete ($i / $VMs.count*100)
# Get Environment tag value
$EnvironmentTag = $null
for ($j = 0; $j -lt $EnvironmentTagList.count; $j++) {
if ($EnvironmentTagList[$j].Entity.Name -eq $VM) {
$EnvironmentTag = $EnvironmentTagList[$j].Tag.Name
}
}
}
😀
The Get-TagAssignment cmdlet is notoriously slow.
As an alternative have a look at the REST based module, see New Community Module for Tag Management
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Thanks. Your suggestion helped speed up the script (obviously!). Now I have to figure out the REST-based module to speed it up even more.
is it possible to add to this script: Datacenter and Clusters where VMs are running?
will be grateful for help.
You can find both via the VM.
Just add these 2 calculated properties
@{N='Datacenter';E={(Get-Datacenter -VM $_).Name}},
@{N='Cluster';E={(Get-Cluster -VM $_).Name}}
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
LucD,
How about adding the OS and a custom property as well? I've tried:
Get-VM | Sort-Object -Property Name |
Get-View -Property @("Name","Config.GuestFullName","Guest.GuestFullName","CustomFields.Item('Description')")
Select -Property Name,
@{N="Configured OS";E={$_.Config.GuestFullName}},
@{N="Running OS";E={$_.Guest.GuestFullName}}
@{N="Description";E={$_.CustomFields.Item('Description')}}
but I get "Get-View Invalid property: CustomFields.Item('Description')
Please explain why the Get-View is needed for the OS and why the CustomFields.Item conflicts.
There is no need of Get-View to list the property required and a couple of mistakes in your line. Here is the working one
Get-VM | Sort-Object -Property Name | Select -Property Name,
@{N="Configured OS";E={$_.ExtensionData.Config.GuestFullName}},
@{N="Running OS";E={$_.Guest.OSFullName}},
@{N="Description";E={$_.CustomFields.Item('Description')}}