VMware Cloud Community
rgb99
Enthusiast
Enthusiast
Jump to solution

Get-VM and CustomFields

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!

Reply
0 Kudos
1 Solution

Accepted Solutions
LucD
Leadership
Leadership
Jump to solution

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

View solution in original post

Reply
0 Kudos
8 Replies
LucD
Leadership
Leadership
Jump to solution

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

Reply
0 Kudos
rgb99
Enthusiast
Enthusiast
Jump to solution

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
        }
    }
}

😀

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

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

Reply
0 Kudos
rgb99
Enthusiast
Enthusiast
Jump to solution

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.

Reply
0 Kudos
maksym007
Expert
Expert
Jump to solution

is it possible to add to this script: Datacenter and Clusters where VMs are running? 

will be grateful for help. 

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

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

Reply
0 Kudos
svillar
Enthusiast
Enthusiast
Jump to solution

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.

Reply
0 Kudos
Sudarshan_Bhart
Enthusiast
Enthusiast
Jump to solution

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')}}

Reply
0 Kudos