Some of you
may have used WMI filtering for Group Policy Objects already. WMI filters are a
smart method to target GPOs dynamically based on properties of the actual
computer system.
http://support.microsoft.com/kb/555253
But from time to time,
a question arises:
How can I target a GPO to
a system that has NOT property xyz?
This translates
to “how can I invert the result of a WMI filter?”
Imagine the
following scenario:
We have a
Domain containing a bunch of Servers. Some of them are Citrix Terminal Servers.
We want to deploy a GPO that is applied to
all Servers except the Terminal Servers.
Or imagine
the following:
We want to
deploy MSI packages via GPO, but only to Computers that do not have a given
software installed (a given executable file is not present).
The
following samples are derived from the first scenario, but I’m sure you’ll
manage to implement them for different situations ;-)What can we filter for?
As you may
know, all Citrix Servers have a service running called “IMAService”, that’s
responsible for keeping the TS Farm connected (shortly spoken, of course). So
our filter to target for TS Servers
may look like this:
Select * from win32_service where name=”IMAService”
This filter
evaluates to true on all TS Servers. But how to convert this to a filter that’s
true on all other servers? Well, first shot:
Select * from win32_service where NOT
name=”IMAService”
See the
mistake? This filter matches on ANY service whose name is not “IMAService”, and
sure this filter will be true on each and every system we have – even on the TS
Servers it will be true.
What now?
Well –
there’s Group Policy Preferences and Item Level Targeting, let’s have a look on
that: We now will combine that with traditional WMI filtering.
This is how it works!
First,
create a new Group Policy Object, navigate to Computer Configuration -
Preferences – Windows Settings – Environment and create 2 items. Both define
the same environment variable, but with a different value.
Please note
that we define the variable “IsTerminalServer” with a value of either 1 or 0.
Then, edit
both items, go to the “Common” tab, optionally check “Remove this item when it
is no longer applied” (not required, but does not matter anyway), and make sure to check “Item-level targeting”:
Now click “Targeting” and in the ILT editor
“New Item” - “WMI Query”. Here’s the
ILT filter for the first entry that sets our variable value to 1:
And here’s
the filter for the second entry that sets our variable value to 0:
The only
difference: The second filter has “Item Options” – “Is Not”, resulting in “does
not return a value” in the filter expression you see.
Note: It’s
even be possible to retrieve properties of the returned object and save them to
(temporary) variables we could use in path or file name fields on the “General”
tab… But we don’t need that feature right now.
Remark: In
the second above mentioned scenario (targeting for the non-existence of a file),
you wouldn’t use a WMI Query – there’s a filter for files already present. I
recommend using the predefined filters whenever possible. In my experience,
they are easy to use and perform very fast. WMI queries tend to be slow...
Here’s all
about Item Level Targeting in detail:
http://technet.microsoft.com/en-us/library/cc733022.aspx
And - unlike Windows in general - within GPP the fabulous "F1" key is always worth being pressed if you need more information...Now link this new GPO to your Domain or any appropriate OU.
What do we have achieved yet?
Well – each
Server that has the IMAService will receive the environment variable
“IsTerminalServer” with a value of 1. All other Servers will receive the same
variable with a value of 0. Half way done ;-)
Now create
one or two WMI filters:
This filter
evaluates to true if “IsTerminalServer” is present and contains “1”. The
presence and content of the variable is controlled by our previously created
GPO with GPP and ILT.
This filter
evaluates to true if “IsTerminalServer” is present and contains “0”. The
presence and content of the variable is controlled by our previously created
GPO with GPP and ILT.
Here’s all about
querying WMI in detail:http://msdn.microsoft.com/en-us/library/windows/desktop/aa392902.aspx
And here’s
all you can query WMI for:
(Most
times, you will only use the Win32 classes anyway…)
Link the
latter WMI filter to your GPO you want to target to all servers EXCEPT Terminal
Servers, and you’re done. The only caveat with this procedure: The GPO using
the WMI filter does not work on first boot, but on the second boot (at first
boot, the GPP Environment has to be processed, but that happens after WMI filters
have been evaluated, so our variable is missing at this very moment…). If you
use the WMI filter in user GPOs, it will work immediately.
Cool, isn’t
it?
Well, to be
honest: The GPP online help suggests using environment variables as an
intermediate mechanism when complex ILT filters
are required – build an environment variable based on a complex ILT filter and
use this environment variable as a simple ILT filter in other GPP elements. But
they forgot to mention the added value when using this with WMI filters.
Stay tuned,
regards Martin