如何递归枚举对象的属性? [英] How to recursively enumerate through properties of object?

查看:52
本文介绍了如何递归枚举对象的属性?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

出于性能方面的考虑,我已经开始重写我的 VMware 每日报告以使用 Get-View,而不是尽可能使用相关的 PowerCLI 命令.这样做的一个小不便是返回的视图对象通常具有许多属性,其中许多属性本身就是对象.一些属性嵌套了四层或更多层.

I've started rewriting my VMware daily report to use Get-View, rather than the related PowerCLI commands wherever possible, for performance reasons. One minor inconvenience with this is that the view objects returned often have many properties, many of which are objects themselves. Some properties are nested four or more levels deep.

所以我正在尝试创建一个函数,该函数将输出对象的所有属性以及该属性的完整路径.然后可以将其传送到 Where-Object,以便更轻松地查找特定属性.因此,要在 $v 中存储的 VMware.Vim.VirtualMachine 对象上查找与 Host 相关的属性,我将键入如下内容:

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

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

理想情况下,这将返回 $v 包含单词Host"的所有嵌套属性的列表.

And ideally, this would return a list of all nested properties of $v which contain the word "Host".

我该怎么做?

推荐答案

也许有更简单的方法可以做到这一点,但我想出了以下方法:

Perhaps there is an easier way to do this, but here's 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's not of a type in our list
                    if (!($typesToExclude.Contains($type) ) )
                    {

                        #Path to property
                        $childPathName = "$PathName.$propName"

                        # Make sure it's 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
}

使用命令运行时

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

它回来了

$_.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

考虑到 VMware.Vim.VirtualMachine 对象具有 5087 个嵌套属性,这是一种更容易找到所需内容的方法.希望这可以帮助其他人.

Considering that the VMware.Vim.VirtualMachine object has 5087 nested properties, this is a much easier way to find what you're looking for. Hopefully this can help someone else.

这篇关于如何递归枚举对象的属性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆