【问题标题】:How to recursively enumerate through properties of object?如何通过对象的属性递归枚举?
【发布时间】:2013-02-04 21:03:31
【问题描述】:

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

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

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

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

我该怎么做?

【问题讨论】:

    标签: powershell powercli


    【解决方案1】:

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

    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 个嵌套属性,这是一种更容易找到所需内容的方法。希望这可以帮助其他人。

    【讨论】:

      猜你喜欢
      • 2017-03-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-12
      • 2010-09-10
      • 2016-01-24
      相关资源
      最近更新 更多