I was reading a thread on the Microsoft Group Policy TechNet Forum today. The gist of it was that someone was trying to filter a domain-linked GPO by OU membership–in other words, either prevent or allow computers in a given OU to receive a domain-linked GPO, based solely on their OU membership. One solution that was proposed was rather roundabout and got me thinking about a better way. The roundabout solution was to do something like create a GP Preferences environment variable and use Item-Level Targeting to target the OU in question. I had highlighted this technique a couple of years ago in this blog post. So, we might create an environment variable called “targetOU” and set it to true if the computer processing the GPP ILT is in that OU. Then we could come along with our original GPO that we wanted to filter by group membership, and create a WMI filter on it that tests the value of that “targetOU” environment variable we just created with the GP Preferences setting.
Like I said, it was a bit roundabout. So I was determined to find a way to do this more directly, using just a WMI filter. I spent some time trolling the WMI namespace, but nothing leapt out immediately. That is, until I remembered that, even though I didn’t think there was a WMI class in root\cimV2 that stored a computer’s OU membership, I knew that Resultant Set of Policy (RS0P) has a namespace in WMI and uses that namespace to store GP RSOP-related data. However, normally that data isn’t present unless you’ve created an RSOP session on that client (i.e. you’ve run GPResults or the GPMC Group Policy Results tool against the computer recently). That said, I did remember that there were several persistent WMI classes under the root\RSOP namespace and looked around in some of them. Bingo! I found what I was looking for. Within the root\rsop\computer namespace, there is a WMI class called RSOP_Session, as shown in my favorite WMI browser, WMIX:
This RSOP_Session class contains a single instance on every machine that I tested, with a number of properties, related to the computer’s role in the domain. The one that I found interesting was the SOM property (there’s also a Site property that lists the computer’s AD site). As you might guess, it contains the LDAP Distinguished Name of the OU that the computer resides in. Bingo again! So, now all I needed to do was create the WMI filter with the appropriate WQL and we’re good to go! That query looks like this:
Note that the namespace field has to reflect the correct namespace, which is root\RSOP\Computer rather than the default root\cimV2. In addition, this query above:
Select * From RSOP_Session Where SOM = 'OU=SDM,DC=cpandl,DC=com'
Evaluates to true if the computer processing the GPO that has this filter is in the particular OU listed. If you want to exclude computers of a particular OU, then you’ll need to make a small modification in the WQL above. Namely:
Select * From RSOP_Session Where NOT SOM = 'OU=SDM,DC=cpandl,DC=com'
In this NOT query above, if the computer is in the OU called SDM, in the domain cpandl.com, then this filter will evaluate to false.
If you’re wondering if this will work on all versions of Windows, I did test this filter in Windows 7 and found the class populated as expected on all versions of Windows from XP to Windows 8 (server products too), so it looks pretty reliable. Performance of the query is good–averaging about 30ms on a given system.
Of course, the primary way to target a GPO to an OU is to simply link the GPO to the OU. But if you can’t do that, or want a more flexible way of DENYING members of an OU the ability to process a given GPO, this method works wonders! I have to say that after all these years of playing with GP, I still am amazed when I find stuff like this to solve problems that have been around for a while. Hopefully you find use in this new way of filtering GPOs based on OU, without having to jump through a bunch of hoops with GPP and ILT or the like.