Active Directory

Group Policy – Monolithic vs Functional Design and Performance Evaluation

/ /
in Blog

Group Policy Design is a hotly discussed topic, with lots of different ideas and discussions.  However, there is not a whole lot of actual metrics.  ADM and ADMX templates apply registry keys in an ‘enforced’ manner.  That is, if you or the machine has access to read the policies, the registry keys within are applied.  If you stuck purely to ADM/ADMX policies but wanted to do dynamic filtering or application of the keys/values based on a set of criteria you’d probably design multiple policies and nested organizational units (OUs).  From here, you could filter certain policies based on the machine or user location in the OU structure or by filtering on the policies themselves and denying access to certain groups or doing explicit allows to certain groups.  This design style, back in the day, was called “functional” design.


However, the alternative style, “monolithic” design, simplifies the group policy object (GPO) design into much fewer GPO’s.



My test setup is very simple; a organizational unit (OU) with inheritance blocked to control the application of the GPO’s.  I created 100 individual GPO’s with a single registry value, and 1 GPO with 100 values.  I chose to do a simple registry addition as it should be the best performance option for group policy.  I created a custom ADMX file for this purpose:

Monolithic simulation:


Functional simulation:



In testing these two designs I elected to focus on the one factor that would have the most impact: latency.  I setup my client machine in the OU, put a WAN emulator that can manipulate latency and measured the performance between the functional and monolithic designs at varying latencies.  I looked for the following event ID’s: 4257, 5257, 4016, 5016.  The x257 events correspond to when group policy downloads the group policy objects off the SYSVOL file share.  The x016 event’s determine how long it took the policy to be processed.


The results:


Raw Data:

Functional GPO – applying 100 registry values
Event ID 4016 to 5016 (ms)
Latency Time (ms)
0 271
10 4089
25 8078
50 15315
75 22904
100 29820
Event ID 4257 to 5257 – Starting to download policies
Latency Time (s)
0 0
10 3
25 6
50 12
75 17
100 22


Monolithic GPO – applying 100 registry values
Event ID 4016 to 5016 (ms)
Latency Time (ms)
0 117
10 156
25 198
50 284
75 336
100 435
Event ID 4257 to 5257 – Starting to download policies
Latency Time (s)
0 0
10 0
25 1
50 1
75 1
100 1



There is a huge edge to the monolithic design.  Both in terms of how long it takes to process a single policy vs multiple policies and the resiliency to the effects of latency.  Even ‘light’ latency can have a profound impact on performance.  Going from 0ms to 10ms increased the length of time to process a functional design by 15 times!  The monolithic design, on the other hand, was barely impacted.  Even with a latency of 100ms, it only added ~300ms of time to process the policy.  I would consider this imperceptible in the real world, where as the functional design going from ~271ms to ~4000ms would be an extremely noticeable impact!  Let alone about 30 seconds at 100ms!

Another factor is how much additional time is required to download the policies.  This is time in addition to the processing time.  This probably shouldn’t be a huge surprise, it appears that group policies are downloaded and processed sequentially, in an order.  I’m sure this is necessary to maintain some semblance of prediction if you have conflicting policies settings, the one last in the list (whether sorted alphabetically or what have you) can be relied on to be the winner.

Adding latency, even just a little latency, has a noticeable impact.  And the more policies, the more traffic, the more the impact of latency.  Again, a loss for a functional design and a win for a more monolithic design.


Group Policy Objects can have a large impact on user experience.  The goal should be to minimize them to as few as possible.  As with everything, there are exceptions to the rules, but for Group Policy it’s important to try and maintain this rule.  Even just a little latency between the domain controller and the client can have a massive impact in group policy performance.  This can impact the length of time it takes a machine to boot, to delaying a user logging into a system.


Read More

The winlogon notification subscriber TermSrv failed a critical notification event.

/ / /

When launching a Citrix application a user was getting a the ‘Citrix launch bar’ then, after a few seconds, it would immediately go away.  Checking the Application log in the event viewer displayed these entries:

The winlogon notification subscriber TermSrv failed a critical notification event. Event ID 6001
The winlogon notification subscriber Sens failed a notification event. Event ID 6004

The root cause?

A faulty path for the homedrive AD attribute:

See that ‘Connect’ H: To ‘Path’?  That was a bad path.

Removing the attribute or fixing it so that it pointed to a path that the user has access to and exists resolved our issue immediately.

Read More

Group Policy Preferences – Scheduled Task fails to apply

/ / /
We had a couple issues with scheduled tasks not applying when submitted as a GPP (Group Policy Preference).  We turned on tracing via local gpedit.msc (Administrative Templates > System > Group Policy > Logging and tracing).  From here we turned on the Scheduled Task logging and events were then stored in the eventvwr.msc (we also turned on tracing which stored a computer.log file here: C:\ProgramData\Group Policy\Trace)
The first error we got was:
So it can’t map between user ID’s.  It’d be nice if it told us which mapping failed, but it gives us a pretty good hint. Looking at the XML file the GPP creates (stored here:  “C:\ProgramData\Microsoft\Group Policy\History\\Machine\Preferences\ScheduledTasks\ScheduledTasks.xml” )
We saw the following:
Everything validates.  Googling for BUILTIN\SYSTEM brought up that several people were getting the same error when using BUILTIN\SYSTEM.  Which makes some sense as “BUILTIN\SYSTEM” isn’t a real account.  We renamed it to NT AUTHORITY\SYSTEM.  This time we got a new error message:
This doesn’t tell us a whole lot of information.  What is the unexpected node? Looking again at the XML file it looked like so:
The difference that I can see:
The SYSTEM account is NOT a group.  We changed how we selected the SYSTEM account by “Browsing” AD, going into the root of the domain, going into the Builtin OU, and selecting SYSTEM.  This populated as “NT AUTHORITY\Well-Known-Security-Id-System”.  This will fail because there is no such user account called “Well-Known-Security-Id-System”.  At this point we renamed it to “NT AUTHORITY\SYSTEM”.
Boom, GPP Scheduled task now worked without issue.  Checking the XML the difference by manually selecting the SYSTEM account changed
If you are having issues with your GPP Scheduled task item running as the SYSTEM account I would HIGHLY recommend you check your XML file and confirm it is set as “NT AUTHORITY\SYSTEM” and it is surrounded by UserId NOT  GroupId.
Read More

Domain Controller doesn’t replicate DNS and has other replication issues

/ / /

We recently demoted a global catalog domain controller and then re-promoted because of issues we were having post-demotion. When a DC is demoted it changes it’s computer account to have less rights then it would if it were a DC. Somewhere along the line the promotion didn’t change it’s account back and after the computer account password expired we started having replications issues. This didn’t really affect us too much until 14 days after the password expired and the DC couldn’t replicate back to the domain. All of our DNS zones couldn’t replicate to it and subsequently became “stale” and were scavenged and removed. This caused issues for everyone at that site as they couldn’t access various resources that we utilize DNS for.

The symptoms were:
All DNS zones were gone except for the primary zone.
“error no trust sam account” occurred while running “nltest /dsregdns”
This error was in the DNS event log:

“The DNS server detected that it is not enlisted in the replication scope of the directory partition ForestDnsZones.ccs.corp. This prevents the zones that should be replicated to all DNS servers in the ccs.corp forest from replicating to this DNS server.

To create or repair the forest-wide DNS directory partition, open the the DNS console. Right-click the applicable DNS server, and then click ‘Create Default Application Directory Partitions’. Follow the instructions to create the default DNS application directory partitions. For more information, see ‘To create the default DNS application directory partitions’ in Help and Support. “

And this error:

The attempt to establish a replication link for the following writable directory partition failed.

dcdiag reported the last replication was 2 weeks ago
repadmin /showreps reported it failed.

The solution was from here:;en-us;329860

WARNING: If you use the ADSI Edit snap-in, the LDP utility, or any other LDAP version 3 client, and you incorrectly modify the attributes of Active Directory objects, you can cause serious problems. These problems may require you to reinstall Microsoft Windows 2000 Server, Microsoft Exchange 2000 Server, or both. Microsoft cannot guarantee that problems that occur if you incorrectly modify Active Directory object attributes can be solved. Modify these attributes at your own risk.
On a domain controller that is in the “healthy” part of the domain (not the domain controller with which you experience the issue), install the Windows 2000 Support Tools if they have not already been installed. For additional information about how to install the Windows 2000 Support Tools, click the article number below to view the article in the Microsoft Knowledge Base:
301423 How to Install the Windows 2000 Support Tools to a Windows 2000 Server-Based Computer
Start the ADSI Edit snap-in. To do so, click Start, point to Programs, point to Windows 2000 Support Tools, point to Tools, and then click ADSI Edit.
Expand Domain NC [] (where server is the name of the domain controller and is the name of the domain.
Expand DC=example,DC=com.
Expand OU=Domain Controllers, right-click CN=ServerName (where ServerName is the domain controller with which you experience the issues that are described in the “Symptoms” section of this article), and then click Properties.
Click the Attributes tab (if it is not already selected).
In the Select which properties to view list, click Both, and then click userAccountControl in the Select a property to view list.
If the Value(s) box does not contain 532480, type 532480 in the Edit Attribute box, and then click Set.
Click Apply, click OK, and then quit the ADSI Edit snap-in

Read More

List of exportable AD attributes

/ / /

It appears the following AD attributes are exportable from LDIFDE or CSVDE:


I’ve exported using CSVDE using all these attributes and managed to import back into a different AD domain (and finding and replacing DC=XXX,DC=COM) and these attributes appear to import cleanly without error

Read More

Group Creation Script

/ / /

The final script:


Read More

LDAP query for *just* users

/ / /

We have numerous “mailbox only” user accounts in our AD. I’ve been asked for a query of all the user accounts on our domain. The query needs to exclude these accounts and disabled accounts as we’re only interested in active user accounts. This is what I came up with:

This query does the following:
Find all user accounts (objectcategory=person)(samaccountname=*)
Disabled accounts (userAccountControl:1.2.840.113556.1.4.803:=2)
Exchange Shared Mailboxes: (msExchRecipientTypeDetails=4)
Exchange Rooms: (msExchRecipientDisplayType=7)
Exchange Equipment: (msExchRecipientDisplayType=8)
Service Accounts: (extensionattribute1=Service Account)

MS Software usually adds “SERVICE ACCOUNT” to the extensionattribute1.

Read More

Saving and restoring ACL’s on OU’s

/ / /

Saving and moving OU ACLs

I’ve written a batch file that will move ACLs from one OU to another. It works by you outputting the results of a ACL from a OU to a text file, specifying the new OU in a batch file and inputting the text file you just created. I use three utilities to accomplish this: adfind.exe, sed.exe and dsacls.exe.
The command to save the text file is:

From here, you need to delete the header in the text file and the footer.
Once that is done, run this script, changing the two variables at the top:

Read More

Generate a CSV from your GPO’s per OU

/ / /

If you come into an environment like I have, you’ll find that some companies prefer to break out their AD structure by location and then generate a OU structure that matches it. Physically, this is understandable and you can understand what’s where. Logically, this causes issues because AD utilizes an inheritance model and this gets complicated and very messy very quickly if you do not follow a strict model. This model falls on its face when you have a centralized IT force. As an example, the company I worked for acquired numerous other companies and a each company/location had it’s own IT workforce. Eventually, the company consolidated all of these external IT departments into one. The IT staff then standardized each site for GPO’s. Which made having each one redundant.

This is a mockup of the OU structure:

And the GPO’s applied:

If you look closely, you can see that some sites are missing some GPO’s, some have an extra GPO, and some have the same. The goal I was given is that I need to consolidate the OU’s with the same GPO’s applied and then I can examine the disparate ones individually. In order to make a nice spreadsheet to do this I created this script (run on Windows, I added awk, sed, and grep to the windowssystem32 folder and installed group policy management).

Since the structure has a nice, predictable “end” OU (eg, Laptops, Desktops, Users) I could script for that keyword:

This generates the following file:

Which looks like this when you put it in Excel:

Nice and pretty and if you add conditional formatting on “x” you can easily identify which OU’s are the same and can be consolidated, or just a nice report on which GPO’s are affecting which OU’s.

Read More

XP – Slow user login, constant prompts for accessing file shares

/ / /

At work we were having an issue that seemed to happen a lot at remote sites. Either login times were glacially slow, users could not access file shares without being prompted over and over again for their credentials and numerous logs of:
Event Type: Warning
Event Source: LSASRV
Event Category: SPNEGO (Negotiator)
Event ID: 40960
Date: date
Time: time
User: N/A
Computer: Computername
Description: The Security System detected an authentication error for the server ldap/dca.acc.local. The failure code from authentication protocol Kerberos was “There are currently no logon servers available to service the logon request. (0xc000005e)”.
For more information, see Help and Support Center at
Data: 0000: c000005e

Event Type: Warning
Event Source: LSASRV
Event Category: SPNEGO (Negotiator)
Event ID: 40961
Date: date
Time: time
User: N/A
Computer: Computername
Description: The Security System could not establish a secured connection with the server ldap/ No authentication protocol was available.
For more information, see Help and Support Center at
Data: 0000: c0000388

The fix to these issues is to switch Kerberos to UDP. After doing so the warnings disappeared and accessing file shares worked without constant reprompting. As well, logins for these remote users became much, much faster.

The change to set Kerberos to UDP is here:

Start Registry Editor.
Locate and then click the following registry subkey:
HKEY_LOCAL_MACHINESystemCurrentControlSetControlLsa KerberosParameters
Note If the Parameters key does not exist, create it now.
On the Edit menu, point to New, and then click DWORD Value.
Type MaxPacketSize, and then press ENTER.
Double-click MaxPacketSize, type 1 in the Value data box, click to select the Decimal option, and then click OK.
Quit Registry Editor.
Restart your computer.

Read More