this code used to work fine for the past year, now it is still working, but i have only 4 groups that generate this error...

the code is simple:

   using (var context = new PrincipalContext(ContextType.Domain, domName))
              {
                  foreach (string grp in myGroups)
                  {
                      using (var group = GroupPrincipal.FindByIdentity(context, IdentityType.Name, grp))
                      {
                          PrincipalSearchResult<Principal> usersList;

                          usersList = group.GetMembers(true);

                          int usersListCount = usersList.Count();
}}}

when these specific groups come to search , i get the group and can see its description in the group object variable, but when getting its members i get an error massage :

base: "There is no such object on the server.\r\n"

ErrorCode: -2147016656

again,this happens only with 4 specific groups from the same domain, and same OU. this just started a few days ago without me changing anything, not permissions, nothing in the code, very strange...

any ideas ?

2

There are 2 best solutions below

0
On

When I encountered this problem I could not have an empty group. I had to produce "best possible" results while the network people were working to resolve the "foreign SID" issue. I know it is a lot extra but it satisfied the auditors so maybe it will help you. This is what I did:

  1. Precursor: I had already built a class that held all the properties of the AD Entity.
  2. Got a list of users and all their group memberships.
  3. Wrapped the call to get members in a try... catch and when this error occurred I inserted a "Group Membership" property of "Error Retrieving members"
  4. When I had iterated through all the Groups I grabbed a list of all groups that had the error message as a group member then queried the Users list to get a list of all the users who were members of that group.
  5. Then inserted Property records with the found users names.

Since this answer is more about solution structure I will only give a very brief outline of the classes used. While far from elegant it gave me a reusable container that was easy to understand and share and provided a solution that was durable across several networks. It probably lacks in many ways but it passes test #1 - it worked.

public class ADPropEntry : IComparable<ADPropEntry>
{
        #region Properties
        public string Name { get { return _name; } set { _adName = value; SetPropVals(_adName); } }
        public string Value { get { return _v; } set { _v = value; DoValConversion(); } }
        public bool IsVisible { get { return _isVis; } set { _isVis = value; } }
        public string ConvertTo { get { return _convertVal; } set { _convertVal = value; } }
        public int ID { get { return _id; } set { _id = value; } }
        #endregion

        private void SetPropVals(string s)
        {
            switch (s)
            {
                case "accountexpires": _name = "Account Expires"; _isVis = false; _convertVal = "FromFileTime"; break;
                ... more handles each property conversion
            }
        }
    }
    public class ADEntity : IComparable<ADEntity>
    {
        #region Properties
        public string Name { get { return _name; } set { _name = value; } }
        public List<ADPropEntry> MyProperty { get { return _ade; } set { _ade = value; } }
        public string EntityType { get { return _entT; } set { _entT = value; } }
        public string ADName { get { return GetProperty("SAM Account Name"); } }
        #endregion
    }

This formed provided me a durable data container and then I used another class to query AD in whatever method makes sense. This was packaged in a DLL that the client application could use.

    class ADAccess
    {
        #region Properties
        public bool HasErrors { get { return (bool)(_errMsg.Length > 10); } }
        public string ErrorMsg { get { return _errMsg; } }
        public List<ADEntity> GroupEntries { get { return _lstGrps; } }
        public List<ADEntity> UserEntries { get { return _lstUsrs; } }
        public List<ADEntity> PrinterEntries { get { return _lstPrts; } }
        public List<ADEntity> ComputerEntries { get { return _lstCmps; } }
        #endregion
    
    public List<ADEntity> GetADListByMSO(string groupType)
    {
        if (groupType == "")
        {
             // get them all return an empty list populating properties
        }
        else
        {
             // set the context and fetch return populated list
        }
    }

Used the same structure to report on SQL server permissions as well.

0
On

i found out the issue, the problematic groups contained users from different domains, once removed these users from the groups , everything went back to work. thanks.