WMI query filters with PowerShell syntax instead of WQL

PowerShell comes already with tight integration to WMI with its built-in Get-WmiObject and Get-CimInstance cmdlets. One of the things that people already familiar with PowerShell syntax bothers about WMI is that it comes with its very own query language WQL. While WQL is very similar to SQL. Wouldn’t it be nicer if we could use the same operators and wild-card patterns we are already familiar with?
Well, for myself the answer is Yes:

Let’s first build a proof of concept before creating a proxy function for Get-WmiObject. We can make us of the (newer) PowerShell parser to identify the different elements of the Filter for conversion and the WildcardPattern.ToWql method to convert the wild-card pattern for the LIKE operator:

All it takes are 35 lines of code to implement the functionality.
Now that we have the proof of concept working we can go ahead and dynamically create the proxy functions for Get-WmiObject and Get-CimInstance to keep it simple we just add an additional parameter (PowerShellFilter) that takes the PowerShell syntax, converts the PowerShell to WQL and passes it on to the ‘Filter’ parameter without worrying about adding an additional parameter set to mutually exclude the ‘Filter’ and ‘PowerShellFilter’ parameters. After retrieving the code for the proxy command using the command meta data we need to add the statements for the new parameter (considering the same parameter sets as for the existing ‘Filter’ parameter) at the the top of the param statement and insert the additional logic between the following lines (e.g. Get-WmiObject)…

if ($PSBoundParameters.TryGetValue('OutBuffer', [ref]$outBuffer))
$PSBoundParameters['OutBuffer'] = 1
$wrappedCmd = $ExecutionContext.InvokeCommand.GetCommand('Microsoft.PowerShell.Management\Get-WmiObject', [System.Management.Automation.CommandTypes]::Cmdlet)

… before creating the new function based on a script block made of the updated code:

Putting the above into your profile (You can read here and here on how to work with profiles) will enable you to use PowerShell syntax with Get-WmiObject and Get-CimInstance:

$state = 'Running'
Get-WmiObject -Class Win32_Service -PowerShellFilter {Name -like '*srv*' -and State -eq $state}
Get-CimInstance -ClassName Win32_Service -PowerShellFilter {Name -like '*srv*' -and State -eq 'Running'}

How do you like PowerShell syntax to query WMI?


Photo Credit: Svedek via Compfight cc