How to make a WMI Filter?
May 9, 2014 2 Comments
WMI Filters are nothing new, but, i believe are not used as widely as perhaps they could be, leading to complex OU structures in your domain just to get GPOs targeted to the right devices. A structured OU policy is fine of course, encouraged even, but there may be circumstances where targeting a GPO is not easy within a given structure, and you don’t want a GPO to apply to other devices that may share an OU. Anyway, none of that really matters here, what i wanted to write about was something that has bugged me since the first time i wanted to use WMI filters. How do i make one?
its easy enough to search around the internet to find examples of pre made WMI filters, or even find one that fits your needs, however what always puzzled me, was the query language itself, and how do i work out if the filter is going to work, without setting up a test machine, or test policy linked to a test WMI filter.
I finally stumbled on the answer yesterday when trying to answer a question on how to target Multipoint Servers in a given OU structure. If you do a search online you will definitely hit on results about using the Windows Version number as a filter, something like this from the Directory Service team blog:
SELECT Version FROM Win32_OperatingSystem WHERE Version < “6”
The above WQL query returns true for any operating systems older than Vista (so Windows XP and Windows Server 2003).
SELECT Version FROM Win32_OperatingSystem WHERE Version LIKE “6.0%”
The above WQL query returns true for only Windows Vista or Windows Server 2008 operating systems.
SELECT Version FROM Win32_OperatingSystem WHERE Version = “5.1.2600”
The above WQL query returns true only if the operating system is Windows XP Service Pack 2.
SELECT * FROM Win32_OperatingSystem WHERE Version LIKE “6.0.%” AND ProductType <> “1”
Which is fine, but it doesn’t fit my needs because Multipoint 2011, shares a common version number with other versions of Server 2008 R2, as does SBS 2011, or Multipoint 2012 with Server 2012.
Having done a fair bit of work with PowerShell over the last two years, i know that there is a value inside WMI named ‘Caption’ which is part of Win32_OperatingSystem. A quick PowerShell command can reveal my OS Caption.
Herein lies my problem. Sure, i know how to reveal this value in PowerShell. but how do i do it in a way that a WMI Filter will apply to the right devices. In other words, how do i write a WMI Query?
Being lazy, i like to copy other peoples work and tweak it for my own purposes. Given that the above code will find me a machine with a version like 6.0 i tried this,
SELECT * FROM Win32_OperatingSystem WHERE Caption LIKE “Microsoft Windows MultiPoint Server 2011*”
Which did not work.
So, then i tried to be more specific.
SELECT * FROM Win32_OperatingSystem WHERE Caption =“Microsoft Windows MultiPoint Server 2011”
Which did not work either, and to be honest, left me more than a little confused.
Every other time i did WMI work i hit this question..
“..there must be a better way to build these filters..”
With this result,
“.. oh well i’ve done it now..”
So this time i decided i really should work on finding a way to do it.
Enter, WBEMTest which is an amazing little utility built into Windows. If you load it up on a machine that you want to target you can run queries against the local machine to find exactly the right value that you need for your filter.
Simply click start, and type in WBEMTest.
I knew that the value i wanted was part of Win32_OperatingSystem
(although at this point i was wondering whether CAPTION was indeed part of this class at all!)
Inside WBEMTest, we can connect to the relevant Namespace, which is root\cimv2.
Once we have done that, we can run a Query.
I just want to find out what values are available as part of Win32_OperatingSystem at this point, so we can search for this:
select * from Win32_OperatingSystem
Really simple query, and hopefully does not need any explanation. The result should be everything from Win32_OperatingSystem.
Once we apply the query, we will see if we get any results or not.
If we do, we can review those results by double clicking on the item shown.
Scrolling down, i found that CAPTION did indeed exist, and what’s more it seemed to match what i had searched for, with one subtle difference.
If you double click on the caption properties, you can see why my query failed.
Oddly, the CAPTION for MultiPoint, seems to have a trailing “ “, so querying for “Microsoft Windows MultiPoint Server 2011” would fail where “Microsoft Windows MultiPoint Server 2011 ” would have succeeded.
Annoying indeed, however you might then wonder why the query i used above using the filter LIKE did not succeed, i certainly was.
Well i decided to find out.
With my new favourite tool i tried out the query i entered above, which resulted in an error.
What i had forgotten, and what was in plain site at the top of the page, is that * is not a wildcard in WMI like it is in PowerShell, rather you need to use a %.
So amending the query to correctly use a wildcard, i got the intended results. I now had a WMI filter i could use to target only Servers running Windows Multipoint.
You can also see my GPO is now no longer denied by WMI, even though it is not actually applied to the computer as it is only an empty test GPO.
Of course this process can be amended to find any value contained within WMI, which is essentially anything you could possibly want to know about any computer on your network.