title: GroupPrincipal.GetMembers fails when group (or child group if recursive) contains ForeignSecurityPrincipal
body: <p><strong>This is not so much a question as information for anyone experiencing the same problem.</strong></p>
  
  <p>The following error occurs:</p>
  
  <pre><code>System.DirectoryServices.AccountManagement.PrincipalOperationException: An error (87) occurred while enumerating the groups. The group's SID could not be resolved. 
  at System.DirectoryServices.AccountManagement.SidList.TranslateSids(String target, IntPtr&amp;#91;&amp;#93; pSids) 
  at System.DirectoryServices.AccountManagement.SidList.ctor(List`1 sidListByteFormat, String target, NetCred credentials) 
  at System.DirectoryServices.AccountManagement.ADDNLinkedAttrSet.TranslateForeignMembers()
  </code></pre>
  
  <p>When the following code is run and a group or child group contains a ForeignSecurityPrincipal:</p>
  
  <pre><code>private static void GetUsersFromGroup()
  {
      var groupDistinguishedName = "CN=IIS_IUSRS,CN=Builtin,DC=Domain,DC=com";
      //NB: Exception thrown during iteration of members rather than call to GetMembers.    
      using (PrincipalContext ctx = new PrincipalContext(ContextType.Domain, "Domain", "Username", "Password"))
      {
          using (GroupPrincipal groupPrincipal = GroupPrincipal.FindByIdentity(ctx, IdentityType.DistinguishedName, groupDistinguishedName))
          {                    
              using (var searchResults = groupPrincipal.GetMembers(true))//Occurs when false also.
              {
                  foreach (UserPrincipal item in searchResults.OfType())
                  {
                      Console.WriteLine("Found user: {0}", item.SamAccountName)
                  }
              }
          }
      }
  }
  </code></pre>
  
  <p><em><strong>I raised a support call with Microsoft and they have confirmed it as an issue.  A bug has been raised internally but it has not been confirmed whether this will be fixed.</em></strong></p>
  
  <p>Microsoft suggested the following workaround code but it performs poorly on groups with a large number of users because of the repeated calls to UserPrincipal.FindByIdentity.</p>
  
  <pre><code>class Program
  {
      //"CN=IIS_IUSRS,CN=Builtin,DC=dev-sp-sandbox,DC=local"; //TODO MODIFY THIS LINE ACCORDING TO YOUR DC CONFIGURATION
  
      static void Main(string[] args)
      {
          if (args.Length != 1)
          {
              Console.WriteLine("Usage: ListGroupMembers \"group's DistinguishedName\"");
              Console.WriteLine("Example: ListGroupMembers \"CN=IIS_IUSRS,CN=Builtin,DC=MyDomain,DC=local\"");
              return;
          }
  
          string groupDistinguishedName = args[0];
  
          PrincipalContext ctx = new PrincipalContext(ContextType.Domain, "dev-sp-dc", "Administrator", "Corp123!");
          List&lt;UserPrincipal&gt; users = new List&lt;UserPrincipal&gt;();
          listGroupMembers(groupDistinguishedName, ctx, users);
  
          foreach (UserPrincipal u in users)
          {
              Console.WriteLine(u.DistinguishedName);
          }
      }
  
      //Recursively list the group's members which are not Foreign Security Principals
      private static void listGroupMembers(string groupDistinguishedName, PrincipalContext ctx, List&lt;UserPrincipal&gt; users)
      {
          DirectoryEntry group = new DirectoryEntry("LDAP://" + groupDistinguishedName);
          foreach (string dn in group.Properties["member"])
          {
  
              DirectoryEntry gpMemberEntry = new DirectoryEntry("LDAP://" + dn);
              System.DirectoryServices.PropertyCollection userProps = gpMemberEntry.Properties;
  
              object[] objCls = (userProps["objectClass"].Value) as object[];
  
              if (objCls.Contains("group"))
                  listGroupMembers(userProps["distinguishedName"].Value as string, ctx, users);
  
              if (!objCls.Contains("foreignSecurityPrincipal"))
              {                    
                  UserPrincipal u = UserPrincipal.FindByIdentity(ctx, IdentityType.DistinguishedName, dn);
                  if(u!=null)  // u==null for any other types except users
                      users.Add(u);
              }
          }                 
      }
  }
  </code></pre>
  
  <p>The above code could be modified to find foreign security principals causing problems in groups.</p>
  
  <p><strong>Microsoft provided the following information about the foreign security principals:</strong></p>
  
  <p>This is a class of objects in AD which represents a security principal from an external source (so another forest/domain or one of the “special” accounts below). 
  The class is documented here: <a href="http://msdn.microsoft.com/en-us/library/cc221858(v=PROT.10).aspx">http://msdn.microsoft.com/en-us/library/cc221858(v=PROT.10).aspx</a>
  And the container is documented here : <a href="http://msdn.microsoft.com/en-us/library/cc200915(v=PROT.10).aspx">http://msdn.microsoft.com/en-us/library/cc200915(v=PROT.10).aspx</a> 
  A FSP is not a real object in AD, but rather a placeholder (pointer) to an object which lives in a different, trusted domain/forest. It can also be one of the “special identities” which are a bunch of well-known accounts who are also classed as FSP’s because their SID’s are different to the domain SID. 
  For example the anonymous, Authenticated User, batch and several other accounts as documented here:
  <a href="http://technet.microsoft.com/en-us/library/cc779144(v=WS.10).aspx">http://technet.microsoft.com/en-us/library/cc779144(v=WS.10).aspx</a></p>