Powershell recursive WMI query

I'd like to start at the top of a WMI namespace, recurse through all the objects, then recurse through each object's property list, filtering out and returning to console only those properties that have mem in their names.

This is what I have so far:

gwmi -namespace "root\cimv2" -list |???? |get-Member -MemberType property | Where-Object { $_.name -match 'mem'}

Notice the big |???? in the middle there. If I remove that, the the command seems to run, but fails to find properties I know should be found. Why? I think it is because I get different output from the following two commands:

gwmi "Win32_operatingSystem"  |get-Member -MemberType property (73 lines of output)
gwmi -namespace "root\cimv2" -list  |where-object { $_.Name -eq 'Win32_OperatingSystem' } |get-Member -MemberType property (10 lines of output)

What I want is a one-liner that recursively concatenates this process:

gwmi -namespace "root\cimv2" -list
(manual selection of a WMI class from the list of 1000+ which appear) 
gwmi "win32_OperatingSystem" | get-Member -MemberType property | Where-Object { $_.Definition -match 'mem' }

Thanks, and if a working answer is given, I will accept and upvote it (annoying when people never do that, isn't it?).

Note added 2009/11/14: I haven't awarded the answer yet because no one has yet provided a one-liner which solves the problem.


I think this will do what you are looking for in one line. the CIMV2 namespace is there by default but if you wanted to select a different one, you can use gwmi -namesapce.

The "trick" is nesting a where-object in side the foreach-object

gwmi -list | % {$_.Properties | ? {$_.Name.Contains('Memory')}} | select Origin,Name

It looks like that this:

gwmi -namespace "root\cimv2" -list

returns an array of ManagementClass .Net objects, so you can use ManagementClass.Properties collection to select properties that have a certain string in their names. Here is my PowerShell script:

foreach($class in gwmi -namespace "root\cimv2" -list)
{
    foreach($property in $class.Properties)
    {
        if($property.Name.Contains('Memory'))
        {
            $class.Name  + ' --- ' + $property.Name
        }
    }
}

As you can see I am a PowerShell beginner, but I think you can make a 'one-liner' from that.


I think by listing the namespace you get WMI CLASS Objects, but not the actual object instances - which you get by gwmi "win32_OperatingSystem" If you use gm you will see:

TypeName: System.Management.ManagementClass#ROOT\cimv2\Win32_OperatingSystem vs TypeName: System.Management.ManagementObject#root\cimv2\Win32_OperatingSystem

edit: You could do something like this:

gwmi -namespace "root\cimv2" -list | %{ gwmi -class $_.name.tostring()}

and if you want all properties with mem* then you could try | select-object "mem*"

but I'm not sure if that is really what you want. I think this is very ineffective if you just need to know the amount of memory. What do you really want to have as output?