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:
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.
The function will also work to bypass PowerShell’s default formatting for WMI objects, making it easier to see all the properties.
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.
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]