I have an issue that I have searched all over the net but didn't find an acceptable cause or resolution.
My aim is to create a console application to get the members of a group and its subgroups. I am able to do so using DirectoryServices. But I wish to make use of the new AccountManagement API as that would uncomplicate my code to a large extent. My code is as under (some names/paths masked)
PrincipalContext insPrincipalContext =
new PrincipalContext(ContextType.Domain,
"my.grp.net",
"DC=my,DC=grp,DC=net",
"domain\\username", "Password"
);
ArrayList users = new ArrayList();
GroupPrincipal oGroupPrincipal =
GroupPrincipal.FindByIdentity(insPrincipalContext,IdentityType.SamAccountName, "My group name");
PrincipalSearchResult<Principal> usrs = oGroupPrincipal.GetMembers(true);
foreach (UserPrincipal p in usrs)
{
if (p != null)
users.Add(p.SamAccountName);
}
This code retrieves a few thousand users and then throws an error as below. If in debug mode I hit F5 to continue, it returns a few thousand more users before throwing the same exception again.
System.DirectoryServices.AccountManagement.PrincipalOperationException was unhandled Message=The specified directory service attribute or value does not exist.
Source=System.DirectoryServices.AccountManagement ErrorCode=-2147016694 StackTrace:
at System.DirectoryServices.AccountManagement.ADStoreCtx.LoadDirectoryEntryAttributes(DirectoryEntry de)
at System.DirectoryServices.AccountManagement.ADDNLinkedAttrSet.MoveNextMemberEnum()
at System.DirectoryServices.AccountManagement.ADDNLinkedAttrSet.MoveNext()
at System.DirectoryServices.AccountManagement.FindResultEnumerator`1.MoveNext()
at System.DirectoryServices.AccountManagement.FindResultEnumerator`1.System.Collections.IEnumerator.MoveNext()
at ManagedActiveDirectoryTrial.Program.Main(String[] args) in C:\Khalid Naseem\Trial\ManagedActiveDirectoryTrial\ManagedActiveDirectoryTrial\Program.cs:line 77
at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart() InnerException: System.Runtime.InteropServices.COMException
Message=The specified directory service attribute or value does not exist.
Source=System.DirectoryServices
ErrorCode=-2147016694
StackTrace:
at System.DirectoryServices.DirectoryEntry.Bind(Boolean throwIfFail)
at System.DirectoryServices.DirectoryEntry.Bind()
at System.DirectoryServices.DirectoryEntry.RefreshCache()
at System.DirectoryServices.AccountManagement.ADStoreCtx.LoadDirectoryEntryAttributes(DirectoryEntry de)
This exception is not of much help to me as I am unable to determine what user and for which attribute is this error thrown.
I am able to retrieve users of the same group and its sub groups using DirectoryServices API but with many lines of code and recursion that I want to avoid.
A resolution to this problem will be highly appreciated.
Thanks - Khalid
It sounds like a scenario where a user may be removed from an Security Group or Distribution List, but has not fully replicated through Active Directory yet. This exception may be thrown if the executable calling this method does not have Admin rights.
To workaround, for the first case, you may want to try to call oGroupPrincipal.GetMembers(false) and write the recursive logic yourself by check if the member is a group and then call GetMembers again for that object.
Other concern may be that GetMembers(true) does not handle circular dependencies.