Showing posts with label Item Level Targeting. Show all posts
Showing posts with label Item Level Targeting. Show all posts

Thursday, April 02, 2015

Environmental surroundings – creating variables to access AD objects



Hi all out there.

If you are working with logon or startup scripts, you usually access computer or user properties through environment variables like %userdomain% or %computername%.

The challenge

Our company often deals with trusts. This means %userdomain% is different from the computer’s domain. Unfortunately there’s no variable %computerdomain% nor %computerdnsdomain%.

In addition, we often access domain, user or computer attributes. Usually, you get the domain from the RootDSE object (https://msdn.microsoft.com/library/aa393248.aspx), but for computers and users, you have to search. And searching results in domain controller load – it would be more convenient if we could bind directly. For that, we need the distinguishedName of our objects.

If we manage to provide distinguished names in environment variables, they can be used easily, and no more searching is required. So we want to provide the following variables:

  • ComputerDomain: The NetBIOS name of the computer’s domain 
  • ComputerDNSDomain: The FQDN of the computer’s domain 
  • ComputerDomainDN: The Distinguished Name of the computer’s domain 
  • ComputerNameDN: The Distinguished Name of the computer account 
  • UserDomainDN: The Distinguished Name of the user’s domain 
  • UserNameDN: The Distinguished Name of the user account 
  • UserSID: The Security Identifier of the user account

The UserSID isn’t really in scope, but hey, we are working on it anyway :-)

Wednesday, April 01, 2015

Wer bin ich und was darf ich - Gruppenmitgliedschaften und Benutzerrechte


Hallo Ihr da im Netz :)

Wenn Ihr eine Domäne verwaltet, dann möchtet Ihr steuern, wer sich an welchen Computern anmelden darf und ob er dort dann Admin oder nur Benutzer ist. Das macht Ihr natürlich mit Gruppenrichtlinien, und Ihr verwendet dafür

  • Eingeschränkte Gruppen - Legt fest, welche Domänengruppen/-benutzer Mitglied welcher lokalen Gruppen werden
  • Zuweisen von Benutzerrechten - Legt fest, welche lokalen oder Domänengruppen welche Rechte bekommen (z.B. lokal oder über RDS anmelden, Zeit oder Zeitzone ändern etc.)

Im Folgenden zeige ich Euch eine Variante für diese Einstellungen, die Euch das Leben deutlich einfacher machen kann.


Saturday, March 28, 2015

Umgib mich - Variablen für AD-Pfade


Hallo miteinander.

Wenn Ihr mit Computerstart- oder Anmeldeskripts arbeitet, verwendet Ihr darin bestimmt gelegentlich %computername% oder %userdomain% und ähnliches.

Die Herausforderung

Wir arbeiten häufig mit Trusts. Dabei ist dann natürlich %userdomain% nicht die Domäne des Computers. Also möchten wir zusätzliche Variablen %computerdomain% und %computerdnsdomain% erstellen.

Außerdem haben wir festgestellt, dass in unseren Skripts auch relativ häufig auf die AD-Objekte von Domäne, Computer oder Benutzer zugegriffen wird. Normalerweise holt man sich die Domäne aus RootDSE. Computer und Benutzer muss man aber im AD suchen. Und eine Suchanfrage erzeugt natürlich Last auf dem Domain Controller – besser wäre es, wenn ich also direkt binden kann. Dazu brauche ich den Distinguished Name meiner Objekte.
Wenn ich diesen Distinguished Name als Umgebungsvariable bereitstelle, kann er beliebig verwendet werden, und niemand muss mehr danach suchen.

Konkret wollen wir folgende Variablen bereitstellen:
  • ComputerDomain: Der Netbios-Name der Computerdomäne
  • ComputerDNSDomain: Der FQDN der Computerdomäne
  • ComputerDomainDN: Der Distinguished Name der Computerdomäne
  • ComputerNameDN: Der Der Distinguished Name des Computerkontos
  • UserDomainDN: Der Distinguished Name der Benutzerdomäne
  • UserNameDN: Der Distinguished Name des Benutzerkontos
  • UserSID: Der Security Identifier des Benutzerkontos 
Die UserSID brauchen wir eigentlich nicht, aber wenn wir schon mal dabei sind :)


Thursday, November 27, 2014

Showdown - WMI Filter vs Item Level Targeting







Hi all.

Again, it's "performance tune-up" time :-)

TL;DR: If you need filtering for GPOs and GPPs, do as little filtering as you can. If you use GPP, put all items for one area into one GPO (registry or printers, eg). If you filter for Registry Items, use collections where possible. And if you have to decide whether to use WMI filter or ILT, it depends - on the cost of your query, on the cost of invoking a GPP CSE just to find it will be filtered anyway, and on the cost of the number of GPP items with filters you have.

In my previous post, I examined WMI filter performance when using SELECT KeyProperty instead of SELECT * in WMI filters for group policy objects. This proves that WMI filters in GPOs behave exactly the same as when executed on a commandline  Now the question came up: What about Group Policy Preferences Item Level Targeting (ILT)? Does it perform better, equal or worse than WMI filters?

Preparing the testing scenario


To verify, I used almost the same setup as before: A testing OU where I blocked inheritance. A simple GPO with a registry preference item. This GPO I copied 200 times and linked all copies to my testing OU. A WMI filter with 5 queries, and an ILT filter with 5 conditions. Since I needed "comparable" queries and filters, I used WMI Win32_Battery and ILT Battery.

Remark: This test scenario requires modyfing a lot of GPOs - adding a WMI filter (which is impossible through PoSh, unfortunately), changing ILT settings and so on. I simply used some lines of PoSh to accomplish that after doing the required changes in my template GPO "WMI vs ILT":

$GPOName = "WMI vs ILT"
$DN = "OU=WMI-Test,OU=Backoffice,OU=Users,OU=Corp Root,DC=corp,DC=contoso,DC=com"
for ( $i=1; $i -le 200; $i++ ){
    Remove-GPO -Name "$GPOName - $i";
    Copy-GPO -SourceName "$GPOName" -TargetName "$GPOName - $i";
    New-GPLink -Name "$GPOName - $i" -Target $DN;
}


This is what my WMI filter looks like:




(Silly, I still know, but still sufficient... Nonsense anyway, because a WMI filter fails when the first query fails.)

And this is what my ILT looks like - I did one ILT using WMI queries and one ILT using the pre defined "Battery" condition. I OR'ed these conditions - AFAIK ILT skips evaluation for AND conditions as soon as the first condition is not met, very much the same like WMI filters do.


(This is the same gobble-di-goo as in the WMI filter...)


(Silly again, but sufficient, too...)

For measurement purposes, this time I opted to use Group Policy Eventlog. I filtered for specific Event IDs, namely 5311 (the last event before GP evaluations starts), 5312 (the first event after GP evaluation finishes) for GPO evaluation and 4016/5016 for GPP extension processing start and end. A list of all GP events can be found in this technet article.

To verify whether CPU performance matters, I used a VM with four virtual processors. I already know WMI filters are single threaded, so they will not benefit from the additional processor power. But I don't know about ILT right now, so let's check this, too... Remaining VM data: Windows 8.1 64 Bit with Update, 8 GB RAM.

Measuring the baseline

The first thing I did was applying my 200 GPOs without any filtering. This gives me the baseline for the time needed anyway for GP Evaluation and Registry Extension Processing. This baseline must be subtracted when comparing WMI and ILT performance in the other tests.


So, our baseline is 14 seconds for evaluating 200 GPOs without WMI filters (~70 ms for each GPO, events 5311/5312). It takes about 46 seconds to process 200 disabled registry items (the highlighted 5016 event) with an "update" action (~230 ms for each item). CPU load was about 25% all the time, which indicates that gpsvc is a completely single threaded process.

Remark: For this test, the registry item was disabled so no registry action happened that could delay the test. In all other tests, the registry item was enabled, but never applied due to filtering - my VM obviously has no battery.

1st Test: WMI filter

Lets verify how the WMI filter performs.

This is a total evaluation time of 27 seconds. Subtracting the baseline time gives 13 seconds for WMI filter evaluation (~6.5 ms for each individual query). Not too bad. And if you wonder why it's 6.5 ms and not 1.3 ms - WMI filters fail when the first query fails. So we only evaluated 200 filters and not 5x200=1000 filters.
The WMI filter for Win32_Battery takes about 7 ms.

2nd Test: ILT with WMI query

The following tests were done after removing the WMI filter and implementing ILT for our registry item. First, let's do the WMI ILT - I expect this to perform equally to the WMI filtering.


Subtracting our baseline (46 seconds) gives 73 seconds, which means 7.3 ms for each query (since we OR'ed the queries, we have 1000 queries to execute). Given that we are testing in a VM and in a multitasking environment, that's almost identical to the WMI filter above. To be honest, that is the expected result.

The ILT WMI query for Win32_Battery takes about 7 ms.

Remark: I verified these 7 ms with PoSh Measure-Command earlier in this blog post where it took about 8.5 ms, but on a less powerful VM. That, too, is almost equal.

3rd Test: ILT with "Battery"

Then I changed the ILT from WMI to Battery, as shown in the screen shots at the beginning.


After subtracting the baseline, this filter lasts 63 seconds which is not a huge gain over the WMI query, but it is a notable gain. We are happy about time savings where ever we can find them, and this one are about 15%. Ok, if we only use one ILT, it is a gain of one millisecond. You get the picture :-)

The ILT Battery query takes about 6 ms.

Remark: In this scenario, the WMI filter would be the perfect choice. Not because it is faster, but because it removes the Registry Extension baseline of 46 seconds, too.

4th Test: 200 GPOs with one item vs one GPO with 200 items

This test is to show how performance can blow up if you take care of your GPO design. If we use 200 GPOs, this means the Registry Extension has to read 200 files (registry.xml) from the GPO Sysvol folder. If we put all these items into one single GPO, it has to read - guess what - only one single file.

This is what the one GPO I use now looks like. Remember these are the same 200 registry items with their 5 ILT filters for Battery as in test #3...


Now I ran GPUPDATE one more time and checked the results.



Ooops - processing time dropped down even below our baseline! That's because our baseline also had to process 200 files from sysvol, which is the real performance issue in this case. Reduce the number of GPOs to a reasonable minimum, and do not spread GPP settings over different GPOs - better use ILT.

For the registry thing above: You can create a collection (basically a kind of folder) that holds all your registry items. And you can do ILT for the whole collection, so you need to filter only once. This is the last timestamp for todays blog post.

 

Bingo - now we do filter only one time.

Conclusion

In this scenario with the given filter for a battery, there is almost no difference in performance between WMI filter and ILT. This might differ for other areas - and if it comes to Installed Software AKA Win32_Product / MSI Query, using ILT is an absolute must.

In the above scenario, we first had 200 WMI filters degrading performance by 27 Seconds. Then we had 200 ILTs with almost the same degradation. Only after putting all ILTs within one GPO, the baseline of 46 seconds vanished. And putting all items in a collection gave the ultimate performance gain. 

The real performance gains do not result from using different types of filtering, but from minimizing the number of filters and, much more, from minimizing the number of SYSVOl accesses. Each area within a GPO has its own settings file in SYSVOL, and all of these must be read to get applied. For ILT, they must even be read if they are not applied because the ILT resides in the same file. On the other hand, WMI filters reside in Active Directory, so they generally are read faster. But they only apply to GPOs as a whole.

My recommendation

Build huge GPOs that hold all settings that apply to almost anybody. Do not built individual GPOs to assign a printer or map a network share - put all of these in one GPO together, so you will have only one Printers.XML and only one DriveMaps.XML. Then use ILT.

Build small GPOs that target individual requirements. For these, use WMI filtering if you have an easy to use filter available. Test the performance of your filter before you deploy. If it's unacceptable, check whether ILT can help. This is especially true for registry items, which we can combine in a collection to minimize filtering.

This recommendation comes without warranties! :-)