Skip to content
Menu
The Lonely Administrator
  • PowerShell Tips & Tricks
  • Books & Training
  • Essential PowerShell Learning Resources
  • Privacy Policy
  • About Me
The Lonely Administrator

Skipping WMI System Properties in PowerShell

Posted on April 25, 2012

One of my favorite techniques when using WMI in PowerShell is to pipe an object to Select-Object and select all properties. Try this:

Manage and Report Active Directory, Exchange and Microsoft 365 with
ManageEngine ADManager Plus - Download Free Trial

Exclusive offer on ADManager Plus for US and UK regions. Claim now!


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.


Behind the PowerShell Pipeline

Share this:

  • Click to share on X (Opens in new window) X
  • Click to share on Facebook (Opens in new window) Facebook
  • Click to share on Mastodon (Opens in new window) Mastodon
  • Click to share on LinkedIn (Opens in new window) LinkedIn
  • Click to share on Pocket (Opens in new window) Pocket
  • Click to share on Reddit (Opens in new window) Reddit
  • Click to print (Opens in new window) Print
  • Click to email a link to a friend (Opens in new window) Email

Like this:

Like Loading...

Related

4 thoughts on “Skipping WMI System Properties in PowerShell”

  1. Shay Levy says:
    April 25, 2012 at 9:28 am

    We can also make use of the -ExcludeProperty parameter of the Select-Object cmdlet to filter out properties that starts with double underscore (system properties):

    Get-WmiObject Win32_OperatingSystem | Select-Object -Property * -ExcludeProperty __*

    1. Jeffery Hicks says:
      April 25, 2012 at 9:34 am

      Yes and no. That will get rid of System properties, but you still get Site, Qualifiers and a few more. I’d have to use an expression like this:

      PS C:\> gwmi win32_bios | Select * -exclude “__*”,Scope,Path,Options,Classpath,Systemproperties,Qualifiers,site,container,Properties

      Which is no where near as sexy. 🙂

  2. Colbert says:
    September 22, 2012 at 12:50 am

    Traps.. more help on traps would be fantastic. I’m still hianvg issues figuring out how to hunt down what I can trap for what error message. I’ve read your page about 100times now and still am missing things.

    1. Jeffery Hicks says:
      September 28, 2012 at 12:33 pm

      There’s really no reason to bother with Traps. Focus on learning how to use Try/Catch.

Comments are closed.

reports

Powered by Buttondown.

Join me on Mastodon

The PowerShell Practice Primer
Learn PowerShell in a Month of Lunches Fourth edition


Get More PowerShell Books

Other Online Content

github



PluralSightAuthor

Active Directory ADSI Automation Backup Books CIM CLI conferences console Friday Fun FridayFun Function functions Get-WMIObject GitHub hashtable HTML Hyper-V Iron Scripter ISE Measure-Object module modules MrRoboto new-object objects Out-Gridview Pipeline PowerShell PowerShell ISE Profile prompt Registry Regular Expressions remoting SAPIEN ScriptBlock Scripting Techmentor Training VBScript WMI WPF Write-Host xml

©2025 The Lonely Administrator | Powered by SuperbThemes!
%d