Share via


Extract user details across Active Directory forests using C#

This post describes how to retrieve member details from a Security group that has members from different forests.

Lets consider the following example:

Security Group name : mydomain\secureSG ( let say this resides in forest 'myforest')

Lets say the following members exist in the above security group,

mydomain\john  (this user belongs to the 'myforest' same as the SG and to the same domain 'mydomain')

otherdomain\bob  (this user belongs to the 'myforest' same as the SG but to a different domain 'otherdomain')

someotherdomain\tom  (this user belongs to a different forest altogether, lets say 'otherforest' and a domain called 'someotherdomain' in that forest)

Now, considering the above scenario, if we want to fetch all the members alias of the above security group we can do the following,

 

 string rootDomain = "LDAP://DC=mydomain,DC=myforest,DC=company,DC=com";



DirectoryEntry domainEntry = new DirectoryEntry(rootDomain);

 
DirectorySearcher search = new DirectorySearcher(domainEntry);



search.Filter = "(cn=secureSG)";



search.PropertiesToLoad.Add("member");



SearchResult result = search.FindOne();



if (null != result && result.Properties["member"].Count > 0)



{



DirectoryEntry gpMemberEntry = null;



for (int counter = 0; counter < result.Properties["member"].Count; counter++)



{



object currentMember = result.Properties["member"][counter];



gpMemberEntry = new DirectoryEntry("LDAP://" + currentMember);



string userAlias = gpMemberEntry.Properties["sAMAccountName"].Value as string;



Console.WriteLine(userAlias);



}



}

Doing this would return the alias for the first 2 members correctly, in this case 'john' and 'bob'.

However, in case of tom, the userAlias would be null.

ie. The output will be

'john'

'bob'


 

To extract the userAlias for tom, we would need to perform the following steps

1. Extract the SID from the member object

2. Create a SecurityIdentifier object from the SID

3. Translate the SID into an NTAccount.

4. Get the userAlias from the NTAccount object.

PS: What is a Security ID (SID). Active Directory automatically assigns SIDs to security principal objects at the time they are created. Security principals are accounts in Active Directory that can be assigned permissions such as computer, group, or user accounts. Once a SID is issued to the authenticated user, it is attached to the access token of the user.

Following is the updated implementation of our sample above,

 

 string rootDomain = "LDAP://DC=mydomain,DC=myforest,DC=company,DC=com";



        DirectoryEntry domainEntry = new DirectoryEntry(rootDomain);

        

        DirectorySearcher search = new DirectorySearcher(domainEntry);

        search.Filter = "(cn=secureSG)";

        search.PropertiesToLoad.Add("member");



        SearchResult result = search.FindOne();



        if (null != result && result.Properties["member"].Count > 0)

        {

            DirectoryEntry gpMemberEntry = null;



            for (int counter = 0; counter < result.Properties["member"].Count; counter++)

            {

                object currentMember = result.Properties["member"][counter];

                gpMemberEntry = new DirectoryEntry("LDAP://" + currentMember);

                string userAlias = gpMemberEntry.Properties["sAMAccountName"].Value as string;

                if (string.IsNullOrEmpty(userAlias))

                {

                    string sid = gpMemberEntry.Properties["cn"].Value.ToString();



                    IdentityReference id = new SecurityIdentifier(sid);

                    string[] account = id.Translate(typeof(NTAccount)).ToString().Split('\\');                }

                    userAlias = account[1];   

                }

                Console.WriteLine(userAlias);

            }

        }

 

The output will now be

'john'

'bob'

'tom'

 

Hope this helps..