PowerShell is beginning to make its way through the enterprise. Now that Windows 7 and Windows 2008 R2 include PS natively, rather than us poor administrators needing to install it wherever we might use it, it's time for me to build a sister to the WMIC Snippets page.
I will start by translating everything from my earlier WMIC page into its PowerShell equivalent. Remember, all of this page is text, so you can copy and paste directly from the page. | Table of Contents |
Some reference links
System, BIOS, Motherboard
There are a couple of interesting things to take notice of in the following examples. First, the commands you type are more verbose than what you'd use with WMIC (here's a
link to the equivalent WMIC samples). That means a bit more typing, but it
also means you learn the true WMI namespace rather than the truncated list of aliases available in WMIC. It also means you use the same syntax every time.
The other interesting thing is, I've provided no formatting arguments in the examples below. PS notices differences in the returned data, and tries to format the output the way you want to see it, automagically. I'm still learning how this works, but apparently if any of the properties is an array, PS uses a columnar format. Otherwise it uses the list format. Of course PS does provide formatting options, as we will see.
PS C:\> get-wmiobject -class "win32_computersystem" -namespace "root\cimv2" | select-object -property domain, EnableDaylightSavingsTime, Manufacturer, Model, PartOfDomain, TotalPhysicalMemory, username
domain : cojones.org
EnableDaylightSavingsTime : True
Manufacturer : LENOVO
Model : 2242CTO
PartOfDomain : True
TotalPhysicalMemory : 4183826432
username : PURGATORY\quux
PS C:\> get-wmiobject -class "win32_bios" -namespace "root\cimv2" | select-object -property Caption, Manufacturer, SMBIOSBIOSVersion, Version
Caption Manufacturer SMBIOSBIOSVersion Version
------- ------------ ----------------- -------
Ver 1.00PARTTBLX LENOVO 6FET56WW (2.02 ) LENOVO - 2020
PS C:\> get-wmiobject -class "win32_baseboard" -namespace "root\cimv2" | select-object -property Manufacturer, Model, Product, SerialNumber, Version
Manufacturer : LENOVO
Model :
Product : 2242CTO
SerialNumber : VF26D8CJ2JZ
Version : Not Available
Processor Info
I've added the NumberOfLogicalProcessors property here, not seen in the WMIC snippets page. Tells you how many cores the CPU has. Notice also that I forgot to specify the namespace, and PS defaulted to root\cimv2. I didn't fuss about proper capitalization, and PS got that right, too.
PS C:\> get-wmiobject -class "win32_processor" |select-object -property deviceID, Addresswidth, MaxClockSpeed, Name, Manufacturer, ProcessorID, NumberofLogicalProcessors
deviceID : CPU0
Addresswidth : 64
MaxClockSpeed : 2401
Name : Intel(R) Core(TM)2 Duo CPU P8600 @ 2.40GHz
Manufacturer : GenuineIntel
ProcessorID : BFEBFBFF00010676
NumberOfLogicalProcessors : 2
Hard Drives
I only want to see the hard drives, which are drivetype 3. See below for the other drivetypes.
Here I show a WQL query within PS - and I show the exact same query being executed in two different ways; first with the more traditional
WQL, and second using the get-wmiobject's
-filter parameter. You can see that the results are the same either way.
PS C:\> get-wmiobject -query "select * from Win32_Logicaldisk where drivetype=3" |select-object -property name, freespace, systemname, filesystem, size, volumeserialnumber
name : C:
freespace : 55371079680
systemname : T500
filesystem : NTFS
size : 128016445440
volumeserialnumber : B896A136
PS C:\> get-wmiobject "Win32_Logicaldisk" -filter "drivetype='3'" |select-object -property name, freespace, systemname, filesystem, size, volumeserialnumber
name : C:
freespace : 55367245824
systemname : T500
filesystem : NTFS
size : 128016445440
volumeserialnumber : B896A136
Member name | Description |
---|
0 | Unknown | The type of drive is unknown. |
1 | NoRootDirectory | The drive does not have a root directory. |
2 | Removable | The drive is a removable storage device, such as a floppy disk drive or a USB flash drive. |
3 | Fixed | The drive is a fixed disk. |
4 | Network | The drive is a network drive. |
5 | CDRom | The drive is an optical disc device, such as a CD or DVD-ROM. |
6 | Ram | The drive is a RAM disk. |
Memory
I'm starting to use the built-in aliases now. Notice that get-wmiobject is shortened to gwmi, and select-object is now shortened to select. When you need to know the aliases of any command within PS, you do get-alias -description get-wmiobject (obviously you may change the arguments to the description parameter).
I've also decided to format the output below, by piping through the format-table directive in the first case, and format-list in the second case.
PS C:\> gwmi "Win32_PhysicalMemory" | select -property BankLabel, Capacity, Caption, MemoryType, speed |format-table
BankLabel Capacity Caption MemoryType speed
--------- -------- ------- ---------- -----
Bank 0/1 2147483648 Physical Memory 21 667
Bank 2/3 2147483648 Physical Memory 21 667
PS C:\> gwmi "win32_operatingsystem" | select -property FreePhysicalMemory, FreeVirtualMemory, TotalVirtualMemorySize, TotalVisibleMemorySize | format-list
FreePhysicalMemory : 1204648
FreeVirtualMemory : 4849600
TotalVirtualMemorySize : 8169640
TotalVisibleMemorySize : 4085768 <---This is the total amount of RAM available to the system
NIC properties
Video
Printers
Other Hardware
Operating System, Service Pack, Hotfixes, Domain
Services
Installed Software
Processes
Event Logs
Users and Groups
Query remote hosts
Windows Installer Provider
Exploring WMI via PowerShell
At the top of this page I have given some reference links, including a link to quite a few (but not all!) of the documented WMI namespaces. This link will come in very handy in your uses of WMI, but it can be a drag to always be skipping back and forth from PS to a web browser. Fortunatelyl, PS has much documentation builtin. Let's explore some of the ways to navigate the vast array of WMI namespaces and classes available, from within PowerShell.
First let's find out what namespaces are available:
PS C:\> Get-WmiObject -Namespace "root" -Class "__NAMESPACE" | Format-List Name
Name : subscription
Name : DEFAULT
Name : CIMV2
Name : Cli
Name : nap
Name : SECURITY
Name : SecurityCenter2
Name : RSOP
Name : WMI
Name : directory
Name : Policy
Name : Interop
Name : ServiceModel
Name : SecurityCenter
Name : MSAPPS12
Name : Microsoft
Name : aspnet
Wow, on my Win7 system, there are quite a few (and you'd find more on a server)! We've barely explored CIMV2 namespace, and it is by far the most interesting of those listed. So let's see what we've got here!
PS C:\> Get-WmiObject -List -Namespace root\CIMV2
NameSpace: ROOT\CIMV2
Name Methods Properties
---- ------- ----------
Win32_DeviceChangeEvent {} {EventType, SECURITY_DESCRIPTOR, TIME_CREATED}
Win32_SystemConfigurationChangeE... {} {EventType, SECURITY_DESCRIPTOR, TIME_CREATED}
Win32_VolumeChangeEvent {} {DriveName, EventType, SECURITY_DESCRIPTOR, TIME_CREATED}
MSFT_WMI_GenericNonCOMEvent {} {ProcessId, PropertyNames, PropertyValues, ProviderName...}
MSFT_NCProvEvent {} {Namespace, ProviderName, Result, SECURITY_DESCRIPTOR...}
MSFT_NCProvCancelQuery {} {ID, Namespace, ProviderName, Result...}
MSFT_NCProvClientConnected {} {Inproc, Namespace, ProviderName, Result...}
MSFT_NCProvNewQuery {} {ID, Namespace, ProviderName, Query...}
MSFT_NCProvAccessCheck {} {Namespace, ProviderName, Query, QueryLanguage...}
Win32_SystemTrace {} {SECURITY_DESCRIPTOR, TIME_CREATED}
Win32_ProcessTrace {} {ParentProcessID, ProcessID, ProcessName, SECURITY_DESCRIPTOR...}
Win32_ProcessStartTrace {} {ParentProcessID, ProcessID, ProcessName, SECURITY_DESCRIPTOR...}
Win32_ProcessStopTrace {} {ExitStatus, ParentProcessID, ProcessID, ProcessName...}
Win32_ThreadTrace {} {ProcessID, SECURITY_DESCRIPTOR, ThreadID, TIME_CREATED}
...
This listing truncated both top and bottom - there's a LOT more! Actually let's take a second to find out how much more:
PS C:\> Get-WmiObject -List -Namespace root\cimv2 |measure-object -Line | format-list
Lines : 1037
Wow again. root\CIMV2 contains over a thousand WMI classes - and each of those will have many properties we can query. But who has time to read all of a thousand lines to find the one we need? So how can we quickly find what we're looking for? I remember that one I liked had the word 'operating' in it. So I will use a where-object filter to find classes which contain that word in their names:
PS C:\> Get-WmiObject -List | Where-Object { $_.name -match 'Operating'}
NameSpace: ROOT\cimv2
Name Methods Properties
---- ------- ----------
CIM_OperatingSystem {Reboot, Shutdown} {Caption, CreationClassName, CSCreationClassName, CSName...}
Win32_OperatingSystem {Reboot, Shutdown... {BootDevice, BuildNumber, BuildType, Caption...}
Win32_OperatingSystemAutochkSetting {} {Element, Setting}
Win32_SystemOperatingSystem {} {GroupComponent, PartComponent, PrimaryOS}
CIM_OperatingSystemSoftwareFeature {} {GroupComponent, PartComponent}
Win32_OperatingSystemQFE {} {Antecedent, Dependent}
That second one looks like it. Let's examine it a little more closely:
PS C:\> gwmi Win32_OperatingSystem |get-Member -MemberType property
TypeName: System.Management.ManagementObject#root\cimv2\Win32_OperatingSystem
Name MemberType Definition
---- ---------- ----------
BootDevice Property System.String BootDevice {get;set;}
BuildNumber Property System.String BuildNumber {get;set;}
BuildType Property System.String BuildType {get;set;}
Caption Property System.String Caption {get;set;}
CodeSet Property System.String CodeSet {get;set;}
CountryCode Property System.String CountryCode {get;set;}
CreationClassName Property System.String CreationClassName {get;set;}
CSCreationClassName Property System.String CSCreationClassName {get;set;}
CSDVersion Property System.String CSDVersion {get;set;}
CSName Property System.String CSName {get;set;}
CurrentTimeZone Property System.Int16 CurrentTimeZone {get;set;}
...
Again the list is truncated. There were 73 lines.
---
Gahh, zoho formatter has gone nuts again. Will continue later with:
OK, want to look at properties that reference memory:
gwmi Win32_OperatingSystem |get-Member -MemberType property | Where-Object { $_.name -match 'mem'}