I am trying to get all members of a (configurable) AD group in my application and I noticed that in some cases I am getting errors such as System.Runtime.InteropServices.COMException (0x80005000).
Getting a DirectoryEntry for the group itself works just fine but the problems occur in this piece of code where I am iterating over the group members:
int membersFound = 0;
while (true)
{
PropertyValueCollection members = group.Properties["member"];
foreach (string member in members)
{
using (DirectoryEntry memberEntry = new DirectoryEntry($"GC://{member}"))
{
memberEntry.RefreshCache(new[] { "objectClass", "msDS-PrincipalName", "displayname", "cn" });
bool isGroup = memberEntry.Properties["objectClass"]?.Contains("group") == true;
string userName = memberEntry.Properties["msDS-PrincipalName"]?.Value?.ToString();
if (!isGroup && !string.IsNullOrEmpty(userName))
{
// ...
}
}
}
if (members.Count == 0)
{
break;
}
membersFound += members.Count;
try
{
group.RefreshCache(new[] { $"member;range={membersFound}-*" });
}
catch (COMException e)
{
if (e.ErrorCode == unchecked((int)0x80072020))
{
break;
}
throw;
}
}
It seems like I cannot simply pass the member string to the DirectoryEntry constructor like I am currently doing because if the string contains certain characters such as "/", I get an exception when calling memberEntry.RefreshCache(). I also noticed that it seems to fix the problem in case of the "/" when I escape it with a backslash before passing it to the DirectoryEntry constructor. However, I do not know what else I need to do here to make sure that my code always works no matter what special characters might be in the member string. Is there any function I can use to format the string which already takes care of this or what do I have to do to prevent any problems caused by special characters in my code?
You will have to escape the slashes yourself. The
memberattribute contains a list of thedistinguishedNameof each member. But indistinguishedName, a forward slash has no special meaning, so the slash isn't escaped. But in an LDAP string, a forward slash does have a special meaning.So just use a string
Replace: