2013-02-20 10 views
7

Zacząłem przepisywanie mojego codziennego raportu VMware, aby korzystał z Get-View, a nie związanych z nim poleceń PowerCLI, gdy tylko było to możliwe, ze względu na wydajność. Jednym drobnym utrudnieniem jest to, że zwrócone obiekty widoku często mają wiele właściwości, z których wiele to same obiekty. Niektóre właściwości są zagnieżdżone na czterech lub więcej poziomach.Jak rekurencyjnie wyliczać poprzez właściwości obiektu?

Próbuję utworzyć funkcję, która wyprowadzi wszystkie właściwości obiektu wraz z pełną ścieżką do tej właściwości. Może to zostać przekierowane do Where-Object, aby ułatwić znalezienie określonych właściwości. Tak aby znaleźć nieruchomość dotyczącą Host na obiekcie VMware.Vim.VirtualMachine przechowywane w $ v, chciałbym wpisać coś takiego:

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

a idealnie byłoby to zwróci listę wszystkich zagnieżdżonych właściwości $ v który zawierają słowo "Host".

Jak mogę to zrobić?

Odpowiedz

11

Być może istnieje łatwiejszy sposób to zrobić, ale oto co wymyśliłem:

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 
} 

Po uruchomieniu go za pomocą polecenia

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

zwraca

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

Biorąc pod uwagę, że obiekt VMware.Vim.VirtualMachine ma zagnieżdżone właściwości 5087, jest to znacznie łatwiejszy sposób na fin d czego szukasz Mam nadzieję, że to pomoże komuś innemu.

Powiązane problemy