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

Select WMI

Posted on May 13, 2010March 15, 2014

I’ve been helping out on some WMI and PowerShell issues in the forums at ScriptingAnswers.com. As I was working on a problem I ended up taking a slight detour to address an issue that has always bugged me. When I run a command like 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 -query "Select Name,Description,Disabled from Win32_UserAccount"

PowerShell wants to return system classes as well.

PS C:\> get-wmiobject -query "Select Name,Description,Disabled from Win32_UserAccount"


__GENUS          : 2
__CLASS          : Win32_UserAccount
__SUPERCLASS     :
__DYNASTY        :
__RELPATH        :
__PROPERTY_COUNT : 3
__DERIVATION     : {}
__SERVER         :
__NAMESPACE      :
__PATH           :
Description      : Built-in account for administering the computer/domain
Disabled         : False
Name             : Administrator
PSComputerName   :

...

The work around has been to pipe the original expression to Select-Object and re-selecting the properties I want. This seems like an unnecessary step. Now, depending on the class I could simple return all WMI objects and then use Select-Object. But I should be able to take advantage of early filtering and use Get-WmiObject as it was intended. So I wrote a function called Select-WMI that will take any WMI-looking object and return the non system properties.

#requires -version 2.0

Function Select-WMI {
<#
.Synopsis
Return non system properties from a WMI Object.
.Description
When using -query and Get-WmiObject, you get system properties included, like __CLASS 
and __SERVER. This function will strip off these properties and only return class properties.  
Use -Populated when you want to get all class properties but only if they have a value
defined. This is similar to piping a WMI object to Select * except in this function
you'll only get properties with a value.
.Parameter InputObject
A WMI object either from a Get-WMIObject expression.
.Parameter Populated
Only return properties that have a defined value.
.Example
PS C:\> Get-WMIObject -query "Select Model,Name,Manufacturer from win32_computersystem" | Select-WMI
Manufacturer               Model                      Name                     
------------               -----                      ----                     
TOSHIBA                    Qosmio X505                SERENITY                 

.Example
PS C:\> Get-WMIObject win32_operatingsystem | Select-WMI
BootDevice                                : \Device\HarddiskVolume1
BuildNumber                               : 7600
BuildType                                 : Multiprocessor Free
Caption                                   : Microsoft Windows 7 Ultimate 
CodeSet                                   : 1252
CountryCode                               : 1
CreationClassName                         : Win32_OperatingSystem
CSCreationClassName                       : Win32_ComputerSystem
CSDVersion                                : 
CSName                                    : SERENITY
CurrentTimeZone                           : -240
DataExecutionPrevention_32BitApplications : True
DataExecutionPrevention_Available         : True
DataExecutionPrevention_Drivers           : True
DataExecutionPrevention_SupportPolicy     : 2
Debug                                     : False
Description                               : 
Distributed                               : False
EncryptionLevel                           : 256
ForegroundApplicationBoost                : 2
FreePhysicalMemory                        : 2346688
FreeSpaceInPagingFiles                    : 4182504
FreeVirtualMemory                         : 6091932
InstallDate                               : 20100120131825.000000-300
LargeSystemCache                          : 
LastBootUpTime                            : 20100511175627.595198-240
LocalDateTime                             : 20100511180234.565000-240
Locale                                    : 0409
Manufacturer                              : Microsoft Corporation
MaxNumberOfProcesses                      : 4294967295
MaxProcessMemorySize                      : 8589934464
MUILanguages                              : {en-US}
Name                                      : Microsoft Windows 7 Ultimate |C:\Wi
                                            ndows|\Device\Harddisk0\Partition2
NumberOfLicensedUsers                     : 
NumberOfProcesses                         : 80
NumberOfUsers                             : 5
OperatingSystemSKU                        : 1
Organization                              : JDH Information Technology Solution
                                            s
OSArchitecture                            : 64-bit
OSLanguage                                : 1033
OSProductSuite                            : 256
OSType                                    : 18
OtherTypeDescription                      : 
PAEEnabled                                : 
PlusProductID                             : 
PlusVersionNumber                         : 
Primary                                   : True
ProductType                               : 1
RegisteredUser                            : Jeff
SerialNumber                              : 00426-065-0389393-86732
ServicePackMajorVersion                   : 0
ServicePackMinorVersion                   : 0
SizeStoredInPagingFiles                   : 4182504
Status                                    : OK
SuiteMask                                 : 272
SystemDevice                              : \Device\HarddiskVolume2
SystemDirectory                           : C:\Windows\system32
SystemDrive                               : C:
TotalSwapSpaceSize                        : 
TotalVirtualMemorySize                    : 8363108
TotalVisibleMemorySize                    : 4182504
Version                                   : 6.1.7600
WindowsDirectory                          : C:\Windows

.Example
PS C:\> Get-WMIObject win32_bios -computername SERVER01 | Select-WMI -Populated
BiosCharacteristics   : {4, 7, 8, 9...}
BIOSVersion           : {TOSQCI - 6040000, Ver 1.00PARTTBL}
Caption               : Ver 1.00PARTTBL
Description           : Ver 1.00PARTTBL
Manufacturer          : TOSHIBA
Name                  : Ver 1.00PARTTBL
PrimaryBIOS           : True
ReleaseDate           : 20100223000000.000000+000
SerialNumber          : Z9131790W
SMBIOSBIOSVersion     : V2.20   
SMBIOSMajorVersion    : 2
SMBIOSMinorVersion    : 6
SMBIOSPresent         : True
SoftwareElementID     : Ver 1.00PARTTBL
SoftwareElementState  : 3
Status                : OK
TargetOperatingSystem : 0
Version               : TOSQCI - 6040000
.Example
PS C:\> Select-wmi (gwmi win32_useraccount) | select -first 1

AccountType        : 512
Caption            : SERENITY\Administrator
Description        : Built-in account for administering the computer/domain
Disabled           : False
Domain             : SERENITY
FullName           :
InstallDate        :
LocalAccount       : True
Lockout            : False
Name               : Administrator
PasswordChangeable : True
PasswordExpires    : False
PasswordRequired   : True
SID                : S-1-5-21-2858895768-3673612314-3109562570-500
SIDType            : 1
Status             : OK
.Inputs
Any WMI or [system.management.managementobject] object
.Outputs
A WMI or [system.management.managementobject] object
.Link
Get-WMIObject
Select-Object
.Link
http://bit.ly/ebmiio

.Notes
 NAME:      Select-WMI
 VERSION:   1.1
 AUTHOR:    Jeffery Hicks (@jeffhicks)
 LASTEDIT:  5/11/2010

      Learn more:
       PowerShell in Depth: An Administrator's Guide
       PowerShell Deep Dives 
       Learn PowerShell 3 in a Month of Lunches 
       Learn PowerShell Toolmaking in a Month of Lunches 

     "Those who forget to script are doomed to repeat their work."

      ****************************************************************
      * DO NOT USE IN A PRODUCTION ENVIRONMENT UNTIL YOU HAVE TESTED *
      * THOROUGHLY IN A LAB ENVIRONMENT. USE AT YOUR OWN RISK.  IF   *
      * YOU DO NOT UNDERSTAND WHAT THIS SCRIPT DOES OR HOW IT WORKS, *
      * DO NOT USE IT OUTSIDE OF A SECURE, TEST SETTING.             *
      ****************************************************************
#>

[CmdletBinding()]
Param(
[Parameter(Position=0,ValueFromPipeline=$True)]
[object[]]$InputObject,
[switch]$Populated
)
Begin {
    write-verbose "Starting $($myinvocation.MyCommand)"
    if ($populated) {
        write-verbose "Populated specified"
    }
} #Begin

Process {
    write-verbose "Analyzing object"
    foreach ($item in $inputObject) {
    #only process objects that look like WMI objects
    if ($item.__CLASS) {
        write-verbose "Found $($item.psbase.properties.count) properties"
        #create an empty array to hold property names
        $properties=@()
        $populatedProperties=@()

        foreach ($property in $item.properties) {
          if ($Populated -AND  $item.($property.name) -ne $NULL) {
           #only add property name if it has a value
           write-verbose "Value confirmed. Adding $($property.name)"
           #the following line will display the property value as a string
           #so you might get funny looking output
           #write-verbose  ($item.($property.name) | out-string)
           $populatedProperties+=$property.name
           }
           else {
           write-verbose "Adding $($property.name)"
           $properties+=$property.name
           }
        }
           write-verbose "Returning WMI Object"
           if ($populated) {
              write-verbose "Returning $($populatedProperties.count) populated properties"
              $item | select $populatedProperties
           }
           else {
              $item | select $properties
           }
    }
      else {

        Write-warning "You did not pass a valid WMI Object"
      }
    } #ForEach
} #Process

End {
    write-verbose "Ending $($myinvocation.MyCommand)"
 } #end
} #end function

I assumed you would run it as part of a pipeline. Now, I can more easily get the information I’m after.
selectwmi

The function will also work to bypass PowerShell’s default formatting for WMI objects, making it easier to see all the properties.
selectwmi-2

But I took this one step further. There are times when all I want are properties that have a value. So Select-WMI has a –Populated parameter so that only populated properties are displayed.

selectwmi-3

Now, you'll only really need this when using the WMI cmdlets. In PowerShell v3 and later you can use Get-CimInstance which by default does not display the system properties.

[updated March 15, 2014]


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

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