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.
Enjoy!
Darren
Although I still think that proper OU structure would prevent these issues, this is a really awesome trick!!
Thank you for sharing it.
Couldn’t agree more Joseph :).
Nice tip Darren, thanks.
I’ve been working heavily with GP Prefs and ILT where I’m using the “site” configuration item to map drives….this I know is a costly as I think the client has to make a call to AD to determine the site….so based on your tips it seems that using a WMI query in ILT to work out the site will be much more efficient?
Cheers,
Carl-
Yes, if the choice is between a site-based ILT, which does have to query AD, and a WMI query that stays local on the box, then the WMI query is usually going to be faster. It does depend upon what you’re querying in WMI but if you are using my OU technique, then yes, much quicker.
Darren
Thanks Darren – I’ll be using this I reckon:
select SITE from RSOP_Session WHERE SITE =
(May help someone else too :))
Hello,
I’ve tried on XP and win 7. In winXP it works fine, but on win7 it returns “access denied” when the normal user logs on. (using in a wmi filter for GPO)
I’ve given privileges to the user in the wmi security and i still get the access denied error when triyng to execute the filter.
Does anyone have any ideas?
Thank you.
Where are you getting “access denied” messages? In the event log? In a GP Results report?
Hi,
I’m running into an issue. I created a wmi filter to prevent a logon script gpo from running when the computer is in a certain OU.
The filter seems to be not running correctly when the login user ID does not have admin rights.
Is there a difference?
FW
I suspect the reason your logon script is failing for a “normal” user is that normal users don’t have permissions to read into the root\RSOP\Computer namespace. This technique is probably better suited to testing for computer membership where GP processing is running in the context of localSystem rather than the user. You may be able to loosen the security on that WMI namespace but I’m not sure it’s worth it for this scenario.
I need to exclude an OU with computers from user gpo. When i apply a filter the gpo is not applicable. If in ou from the filter or not. When i delete the filter, gpo is back.
What am i missing?
This is a great alternative for determining what OU is in play based on RSOP_Session. But there is a warning here for those that may not understand that we are always looking over our shoulder when relying on RSOP_Session, due to it’s true nature of being a record of the LAST application of GPO.
Consider this:
You have a GPO that maybe tattoos some portion of the registry or have a GPP that does the same thing and you do NOT want it to apply to a specific OU. So you set a WMI filter to exclude that OU based on SOM RSOP_Session. Well and good for existing computers in that OU since their RSOP_Session would already show that last time it was applied, they were in that same OU. But now you join a new computer to the domain and have it immediately sit in that OU. Because it’s RSOP_Session data will likely show as “Local” (since it wasnt on a domain) or blank or something else, the GPO would apply because RSOP_Session SOM sure wouldn’t show the OU it is now in since it just got there. 🙂
So, as long as youy undertstand that you’re looking back in time when using this, then you should be good to go and won’t be suprised at some strange results that are actually quite predictable.
Good point Harry (and sorry for the late response!). Thanks for bringing up that limitation in this particular class.
Darren
Thanks Darren!
This is great for my use case as well. I want to apply different site level GPOs to the same OU. This should do the trick.
Can this be tested with PowerShell?
I get an error of: Invalid class “RSOP_Session”
When I try to run:
Get-WmiObject -Query “Select * From RSOP_Session Where NOT SOM = ‘OU=Exclude,DC=contoso,DC=com'”
Matthew-
You have to use the -Class parameter to specify the correct namespace (as noted in the article).
Darren