GroupPrincipal throwing "System.Runtime.InteropServices.COMException (0x8007200A): The specified directory service attribute or value does not exist."

3

I'm using System.DirectoryServices.AccountManagement to query for a user and then find the groups for that user.

var _principalContext = new PrincipalContext(ContextType.Domain, domainAddress, adContainer, adQueryAccount, adQueryAccountPassword);
var user = UserPrincipal.FindByIdentity(_principalContext, IdentityType.SamAccountName, account);
var userGroups = user.GetGroups(); 

foreach (var group in userGroups.Cast<GroupPrincipal>())
{
    //////////////////////////////////////////////////////
    // getting the underlying DirectoryEntry shown
    // to demonstrate that I can retrieve the underlying
    // properties without the exception being thrown
    DirectoryEntry directoryEntry = group.GetUnderlyingObject() as DirectoryEntry;

    var displayName = directoryEntry.Properties["displayName"];

    if (displayName != null && displayName.Value != null)
        Console.WriteLine(displayName.Value);
    //////////////////////////////////////////////////////

    Console.WriteLine(group.DisplayName);// exception thrown here...
}

I can grab the underlying DirectoryEntry object and dump its properties and values but as soon as the GroupPrincipal.DisplayName property (or any property for that matter) is accessed, it throws the following exception:

"System.Runtime.InteropServices.COMException (0x8007200A): The specified directory service attribute or value does not exist.\r\n\r\n at System.DirectoryServices.DirectoryEntry.Bind(Boolean throwIfFail)\r\n at System.DirectoryServices.DirectoryEntry.Bind()\r\n at System.DirectoryServices.DirectoryEntry.get_SchemaEntry()\r\n at System.DirectoryServices.AccountManagement.ADStoreCtx.IsContainer(DirectoryEntry de)\r\n at System.DirectoryServices.AccountManagement.ADStoreCtx..ctor(DirectoryEntry ctxBase, Boolean ownCtxBase, String username, String password, ContextOptions options)\r\n at System.DirectoryServices.AccountManagement.PrincipalContext.CreateContextFromDirectoryEntry(DirectoryEntry entry)\r\n at System.DirectoryServices.AccountManagement.PrincipalContext.DoLDAPDirectoryInitNoContainer()\r\n at System.DirectoryServices.AccountManagement.PrincipalContext.DoDomainInit()\r\n at System.DirectoryServices.AccountManagement.PrincipalContext.Initialize()\r\n at System.DirectoryServices.Account Management.PrincipalContext.get_QueryCtx()\r\n at System.DirectoryServices.AccountManagement.Principal.HandleGet[T](T& currentValue, String name, LoadState& state)\r\n at System.DirectoryServices.AccountManagement.Principal.get_DisplayName()\r\n at ConsoleApplication9.Program.Main(String[] args)"

Why would I be able to dump the raw properties of the underlying DirectoryEntry but not be able to call any of the properties directly on the GroupPrincipal? What would cause this exception? Note that this does not happen on the "Domain Users" group but the subsequent groups, it does...

c#-4.0
active-directory
account-management
groupprincipal
asked on Stack Overflow Apr 17, 2013 by Jim • edited Apr 17, 2013 by Jim

2 Answers

5

I found the solution. If I pass the context to the GetGroups method, it works.

var user = UserPrincipal.FindByIdentity(_principalContext, IdentityType.SamAccountName, account);
var userGroups = user.GetGroups(_principalContext);

Apparently, this limits the groups retrieved to the domain associated with the context. Although this is not intuitive because the context was used to retrieve the user in the first place!!!

This leads me to believe there must be groups from other domains being returned previously and permissions were as such to prevent accessing that information.

answered on Stack Overflow Apr 17, 2013 by Jim
0

Why are you using the .GetUnderlyingObject() call? Seems totally superfluous... just use the .SamAccountName property of the GroupPrincipal directly...

Try this:

foreach (var group in userGroups.Cast<GroupPrincipal>())
{
    Console.WriteLine(group.SamAccountName);
    Console.WriteLine(group.DisplayName);
    Console.WriteLine(group.IsSecurityGroup);
}

Seems a lot easier - no?

answered on Stack Overflow Apr 17, 2013 by marc_s

User contributions licensed under CC BY-SA 3.0