How to recursively enumerate properties of an object?

I started rewriting the VMware daily report to use Get-View, and not the corresponding PowerCLI commands, where possible, for performance reasons. One minor inconvenience is that returned view objects often have many properties, many of which are objects. Some properties are nested at four or more levels in depth.

So, I'm trying to create a function that displays all the properties of an object along with the full path to this property. This could then be transferred to the Where-Object folder to make it easier to find specific properties. So, to find the property related to Host on the VMware.Vim.VirtualMachine object stored in $ v, I would type something like:

Get-Properties -Object $v | ? {$_ -match "Host"} 

And ideally, this will return a list of all $ v nested properties containing the word "Host".

How can i do this?

+7
source share
1 answer

There may be an easier way to do this, but here is what I came up with:

 function Get-Properties($Object, $MaxLevels="5", $PathName = "`$_", $Level=0) { <# .SYNOPSIS Returns a list of all properties of the input object .DESCRIPTION Recursively .PARAMETER Object Mandatory - The object to list properties of .PARAMETER MaxLevels Specifies how many levels deep to list .PARAMETER PathName Specifies the path name to use as the root. If not specified, all properties will start with "." .PARAMETER Level Specifies which level the function is currently processing. Should not be used manually. .EXAMPLE $v = Get-View -ViewType VirtualMachine -Filter @{"Name" = "MyVM"} Get-Properties $v | ? {$_ -match "Host"} .NOTES FunctionName : Created by : KevinD Date Coded : 02/19/2013 12:54:52 .LINK http://stackoverflow.com/users/1298933/kevind #> if ($Level -eq 0) { $oldErrorPreference = $ErrorActionPreference $ErrorActionPreference = "SilentlyContinue" } #Initialize an array to store properties $props = @() # Get all properties of this level $rootProps = $Object | Get-Member -ErrorAction SilentlyContinue | Where-Object { $_.MemberType -match "Property"} # Add all properties from this level to the array. $rootProps | ForEach-Object { $props += "$PathName.$($_.Name)" } # Make sure we're not exceeding the MaxLevels if ($Level -lt $MaxLevels) { # We don't care about the sub-properties of the following types: $typesToExclude = "System.Boolean", "System.String", "System.Int32", "System.Char" #Loop through the root properties $props += $rootProps | ForEach-Object { #Base name of property $propName = $_.Name; #Object to process $obj = $($Object.$propName) # Get the type, and only recurse into it if it is not one of our excluded types $type = ($obj.GetType()).ToString() # Only recurse if it not of a type in our list if (!($typesToExclude.Contains($type) ) ) { #Path to property $childPathName = "$PathName.$propName" # Make sure it not null, then recurse, incrementing $Level if ($obj -ne $null) { Get-Properties -Object $obj -PathName $childPathName -Level ($Level + 1) -MaxLevels $MaxLevels } } } } if ($Level -eq 0) {$ErrorActionPreference = $oldErrorPreference} $props } 

When started using the command

 Get-Properties -Object $v | ? {$_ -match "Host" } 

he returns

 $_.Capability.HostBasedReplicationSupported $_.Client.CertificateError.Method.DeclaringType.Assembly.HostContext $_.Client.CertificateError.Method.Module.Assembly.HostContext $_.Client.CertificateError.Method.ReflectedType.Assembly.HostContext $_.Client.CertificateError.Method.ReturnType.Assembly.HostContext $_.Client.ServiceContent.HostProfileManager $_.Client.ServiceContent.HostProfileManager $_.Client.ServiceContent.HostProfileManager.Type $_.Client.ServiceContent.HostProfileManager.Value $_.Config.Hardware.Device.Backing.HostPointingDevice $_.Config.Hardware.Device.Backing.HostPointingDevice $_.Config.Hardware.Device.Backing.HostPointingDevice $_.Config.Hardware.Device.Backing.HostPointingDevice $_.Config.Hardware.Device.Backing.HostPointingDevice $_.Config.Hardware.Device.Backing.HostPointingDevice $_.Config.Hardware.Device.Backing.HostPointingDevice $_.Config.Hardware.Device.Backing.HostPointingDevice $_.Config.Hardware.Device.Backing.HostPointingDevice $_.Config.Hardware.Device.Backing.HostPointingDevice $_.Config.Hardware.Device.Backing.HostPointingDevice $_.Config.Hardware.Device.Backing.HostPointingDevice $_.Config.Tools.SyncTimeWithHost $_.Guest.HostName $_.Guest.IpStack.DnsConfig.HostName $_.Guest.Net.DnsConfig.HostName $_.Runtime.Host $_.Runtime.Host $_.Runtime.Host.Type $_.Runtime.Host.Value $_.Summary.Guest.HostName $_.Summary.QuickStats.HostMemoryUsage $_.Summary.Runtime.Host $_.Summary.Runtime.Host $_.Summary.Runtime.Host.Type $_.Summary.Runtime.Host.Value 

Given that the VMware.Vim.VirtualMachine object has 5087 attached properties, this is a much simpler way to find what you are looking for. Hope this helps someone else.

+11
source

All Articles