One of my favorite techniques when using WMI in PowerShell is to pipe an object to Select-Object and select all properties. Try this:
get-wmiobject win32_bios | select *
It works, but it also gets all of the system properties like __PATH which I rarely care about. I also get other properties like Site and Options which I typically don’t need. So here are some techniques you can use to view all WMI properties that probably matter most. Let’s begin with a typical command:
$os=get-wmiobject Win32_OperatingSystem
This object has a property called Properties which is a collection of WMI PropertyData objects. I could try something like:
PS C:\> $os.properties | select name,value
Name Value
---- -----
BootDevice \Device\HarddiskVolume1
BuildNumber 7601
BuildType Multiprocessor Free
Caption Microsoft Windows 7 Ultimate
CodeSet 1252
CountryCode 1
...
Sure, I can see the properties and values but I don’t really have a good object to work with and this won’t help with multiple instances, at least not without a little extra work.
$d=Get-WmiObject win32_logicaldisk -filter "drivetype=3"
$d | foreach {$_.properties | select name,value }
And maybe that’s all you need. If so, terrific. But I’m looking for an elegant solution. How about expanding the property names and saving them as an array of strings.
[string[]]$prop=$os.properties | Select -expand name
$os | Select -Property $prop
Then I can use them with Select-Object
PS C:\> $os | Select -Property $prop
PS C:\> $os | Select -Property $prop
BootDevice : \Device\HarddiskVolume1
BuildNumber : 7601
BuildType : Multiprocessor Free
Caption : Microsoft Windows 7 Ultimate
CodeSet : 1252
CountryCode : 1
...
That has promise. I could even turn this into a one-line command, assuming I’ve already defined $os.
$os | Select -property ([string[]]($os.properties | Select -expand name))
If I didn’t want to take the extra step, here’s a complex alternative:
Get-WmiObject win32_OperatingSystem | foreach {
Select -InputObject $_ -Property ([string[]](Select -InputObject $_ -expand Properties | Select -expand Name))
}
But this leads to yet another option, using the [WMIClass] type accelerator. When used, PowerShell creates an empty object of the specified WMI class which includes a property list.
PS C:\> [wmiclass]"win32_operatingsystem" | Select -expand Properties | Select name
Name
----
BootDevice
BuildNumber
BuildType
Caption
CodeSet
CountryCode
...
This can be further simplified:
([wmiclass]"win32_operatingsystem").Properties | Select -expand Name
In fact, I can use this in an earlier expression to get the same non-System class results.
get-wmiobject win32_operatingsystem | select -property ([string[]](([wmiclass]"Win32_Operatingsystem").properties | select -expand name))
I’ll admit that’s a lot to type. So I need a shortcut. What about turning this into a scriptblock?
$p={[string[]](([wmiclass]"Win32_Operatingsystem").properties | select -expand name)}
When I invoke the scriptblock, I’ll get the array of property names. I can now use this in my Get-WMIObject expression:
get-wmiobject win32_operatingsystem | select -property (&$p)
Definitely easier to type, but limited. I need the scriptblock to be more flexible so it can accommodate other WMI classes.
$p={Param([string]$class) [string[]](([wmiclass]$class).properties | select -expand name) }
I’ll test it in the shell.
PS C:\> &$p "win32_bios"
BiosCharacteristics
BIOSVersion
BuildNumber
Caption
CodeSet
CurrentLanguage
...
Excellent! Now for the real deal:
PS C:\> get-wmiobject win32_bios | select -property (&$p "win32_bios")
BiosCharacteristics : {4, 7, 8, 9...}
BIOSVersion : {TOSQCI - 6040000, Ver 1.00PARTTBL}
BuildNumber :
Caption : Ver 1.00PARTTBL
CodeSet :
CurrentLanguage :
Description : Ver 1.00PARTTBL
...
That’s exactly what I wanted with minimal effort. All I need is to have that scriptblock loaded in my PowerShell session and remember to specify the class name.
get-wmiobject win32_logicaldisk -filter "drivetype=3" | select -property (&$p "win32_logicaldisk")
Another option would be to turn the scriptblock into a function, but I’ll leave that to you.
Naturally this isn’t perfect. If I need to query a remote computer with classes that aren’t on my computer, this won’t work; at least not without some revisions. But since I’d say 90% or more of WMI commands in PowerShell are with the Win32 classes, I think this is a handy trick to stick in your PowerShell toolbox.
If you’d like to try some of my code samples, you can download demo-wmiproperties.

