I've get an Active Directory Domain in which I create group objects under a certain newly created OU as shown below, e.g. the groups under SubOuB. The global groups under GlobalGroups are already there.
+MainOu
+--SubOuA
+--GroupA_A
+--GroupA_B
+--GroupA_C
+--SubOuB
+--GroupB_A
...
+GlobalGroups
+--GlobalGroupA
+--GlobalGroupB
...
Now I want to add the newly added groups under the newly created OU as members to one of the global groups, e.g. add GroupA_A as a member to GlobalGroupB:
using( PrincipalContext principalContext =
new PrincipalContext( ContextType.Domain, Environment.UserDomainName ) )
{
GroupPrincipal groupPrincipal = GroupPrincipal.FindByIdentity(
principalContext, "GlobalGroupB" );
if( groupPrincipal != null )
{
// Target group found.
groupPrincipal.Members.Add( principalContext, IdentityType.Name, "GroupA_A" );
// The next line throws a NoMatchingPrincipalException.
groupPrincipal.Save();
}
}
When I look at the AD structure and objects I can see both objects. The ADSI Editor shows me that both "names" are correct. When I manually run the code on its own in a test application after the new OU and group objects are created, adding the group as a member to the global group also works fine. All of the code I used works in a staging environment with an AD of the same structure, so I'm not sure why it does have problems in the productive environment.
Any ideas? I've seen that DirectoryEntry
objects have a RefreshCache
method that forces to reload the property values of the particular object, but I don't think that this is going to help here. Is my problem a timing problem? Can I force to "reload" the existing objects so the newly created group is found and can be added to the global group?
Update
This definitely seems to be a problem with the AD synchronisation - when I continuously check for the existence of the newly created group object (e.g. loop with a Thread.Sleep( 1000 )) my code works as expected. The drawback is that I don't know how long I'll have to wait (tests varied between 6 and 15 seconds in my environment) and I also think this is a very dirty approach. Unfortunately I couldn't find any information about how to "refresh" the AD objects or "flush" the cache.
Update 2
When I connect to a specific domain controller, the first query is slow (3000+ milliseconds), subsequent queries are faster and all take about the same time to return. I still don't know how I can avoid to periodically query the AD until the expected object is indeed available (as a query result).
As far as I know the only ways to solve my problem are as follows:
Domain.DomainControllers
and query each of them until your object was foundI don't like either way too much, but I couldn't find any other options. Please feel free to suggest better alternatives.