Friday, August 22, 2014

Powershell and WMI cheatsheet

I finally bit the bullet and spent a bit of time learning some powershell and WMI querying basics. Unfortunately lots of the tutorials and intros out there are missing key pieces that make it usable, like aliases. So here's my cheatsheet as an attempt to remedy that problem.

Listing Classes and Namespaces

First of all, figuring out what information is available is not that easy. It's in classes inside nested namespaces. There's good online documentation, but I'd prefer to get it from the tool itself where I can see the values on a live system. So, lets start with listing all the top-level WMI Namespaces.
PS C:\> Get-WmiObject -class __Namespace -namespace root | Format-Table name

name
----
subscription
DEFAULT
cimv2
Cli

[snip]
Note that Namespaces can be nested, the following ones sit below root\cimv2 which is the default namespace for Get-WmiObject if you don't specify one. If you really want to see everything you're going to need to list them recursively.
PS C:\> Get-WmiObject -class __Namespace -namespace root\cimv2 | Format-Table name

name
----
Security
sms
power
ms_409
TerminalServices
Applications
To list all classes within a namespace (see here for a high-level description of the naming scheme for classes):
PS C:\> Get-WmiObject -List -namespace root\cimv2 | Select name
All classes with 'Net' in the name:
PS C:\> Get-WmiObject -List | Where-Object { $_.name -match 'net'} | Select Name

Retrieving Object Values

Retrieve the class values:
PS C:\> Get-WmiObject -class Win32_NetworkAdapterConfiguration

DHCPEnabled      : True
IPAddress        : {192.168.0.10, abcd::eff:fff:aaaa:abdc}
DefaultIPGateway : {192.168.0.1, abce::eff:feff:aaaa:265}
DNSDomain        : blah.com
ServiceName      : 
Description      : Intel(R) Gigabit Network Connection
Index            : 7

Aliases and Functions

Sick of typing 'Get-WmiObject' yet? Thankfully 'gwmi' is an alias for Get-WmiObject:
PS C:\> gwmi -class Win32_NetworkAdapterConfiguration
The list of built-in aliases can be retrieved with:
PS C:\> get-alias

CommandType     Name
-----------     ----
Alias           % -> ForEach-Object
Alias           ? -> Where-Object
Alias           ac -> Add-Content
Alias           asnp -> Add-PSSnapin
Alias           cat -> Get-Content
Alias           cd -> Set-Location
[snip]
Microsoft has some good doco on aliases here. You can define your own aliases for cmdlets. If you want to do something more complicated you'll need a function:
PS C:\> Function NetIFs {gwmi -class Win32_NetworkAdapter}
PS C:\> Set-Alias nif NetIFs

SQL-like querying, where "select *" doesn't mean everything

To query inside the class you can do this:
gwmi -query "Select * from Win32_NetworkAdapterConfiguration where IPEnabled=1"
There is a gotcha here however. The WMI query will return all the properties of the object, but powershell won't display them all. So you will be missing most of the properties and values listed in the documentation. To see all object properties and values, you can use the Select-Object cmdlet (alias select):
gwmi -query "Select * from Win32_NetworkAdapterConfiguration where IPEnabled=1" | select *
For advanced powershell examples, there's lots of good stuff on tasteofpowershell.blogspot.com.