Connect to an Active Directory and retrieve Users and their information

This post will explain how you would connect to an local Active Directory (AD), and also how to retrieve the AD information about each user such as the user SID, and how we can update each user in a SQL table with this information.

I have a class that looks like this containing some properties. Properties like UserId is something I would like to update from the AD, and UserName is a the property I want to use to retrieve data from the AD, each person in my table contains the correct DisplayName under the UserName field.

So imagine you have a SQL table of persons (or users) and have a class like this with an UserName property and an UserId property along with other properties you might want to update from the AD, this is how you could go about it.

using System;
using System.Collections.Generic;

namespace MyApp.Model
{
    [IncludeInTSGeneration]
    public class Person
    {
        public string UserId { get; set; }
        public string UserName { get; set; }

    }
}

Now let’s build a method for getting users from the Active Directory but first, take a look at the administrator account I have here from the Active Directory.

Nothing special properties-wise about this user, and most fields are empty. Let’s see how we build up a method to get the administrator data though!

public List < Model.Person > UpdateUsersFromAD() {
  // Get all users here and map them
  List < Model.Person > users = myPersonRepository.GetAllUsers();

  using(var ctx = new PrincipalContext(System.DirectoryServices.AccountManagement.ContextType.Domain)) {
    // find a user called administrator
    UserPrincipal user = UserPrincipal.FindByIdentity(ctx, "administrator");

    if (user != null) {
      // Get the SID
      var usersSid = user.Sid;

      // DisplayName should be null since it is empty in our AD.
      var username = user.DisplayName;
    }

  }

  return users;
}

Now we’ve created a method called UpdateUsersFromAD. Now I will not go into the GetAllUsers method but it’s a simple Entity Framework method along with a map method to make us have all Model.Persons into a list called users. We do nothing yet with this List but we will, then we will using the PrincipalContext and pass in the AD DS store, see the different options of the ContextTypes here.

Then we will use UserPrincipal.FindByIdentity where we pass the context (ctx) and also pass along “administrator”. This is the login name used in the AD.

Then we have access to the user in the AD and his or hers properties like so user.Sid or user.DisplayName for example. If you debug you can see the administrator indeed has a Sid and NULL in DisplayName.

While in debug mode

If you add a DisplayName for the AD user it will appear under the DisplayName property as well (see the image).

Now how can we achieve this with a whole list of users? Let’s take a look.

public List<Model.User> UpdateUsersFromAD()
{
    // Get all users here and map them
    List<Model.User> users = myPersonRepository.GetAllUsers();

    using (var ctx = new PrincipalContext(System.DirectoryServices.AccountManagement.ContextType.Domain))
    {
        // Loop through users
        for(int x = 0; x < users.Count; x++)
        {
            // find a user
            UserPrincipal user = UserPrincipal.FindByIdentity(ctx, users[x].UserName);

            if (user != null)
            {
                // Set SID
                users[x].UserId = user.Sid.ToString();
            }
        }

    }

    return users;
}

What we did now is that we’ve added a for loop where we basically do the same thing as before where we fetch the user with username, but this time we use the actual users[x].UserName property from our object, and then we set the Sid as a string to the UserId property. Then in the end return users as before. You could now do a debug and see if our users got a match and now have SIDs updated. And there you go, you have successfuly updated your users with the data of the AD properties.

To make it more complete, lets add a database column in SQL for our UserId property. Note that your SQL column for the SID should be at least 256 characters.

SID is a string with a maximum length of 256 characters.

MS About SID

This SQL column is going to be mapping to our UserId Person property, remember the above statement that the SQL column for SID should be at least 256 character long. Example of a SID: “S-1-5-21-3796585825-3479577636-1793717433-4013”

I have now created a UserId column of the type nvarchar(256) in my persons SQL table. Let’s add some more C# code.

public List<Model.User> UpdateUsersFromAD()
    {
        // Get all users (method returns mapped Model.User objects)
        List<Model.User> users = myPersonRepository.GetAllUsers();

        using (var ctx = new PrincipalContext(System.DirectoryServices.AccountManagement.ContextType.Domain))
        {
            for (int x = 0; x < users.Count; x++)
            {
                // find a user on their logon name
                UserPrincipal user = UserPrincipal.FindByIdentity(ctx, users[x].UserName);

                if (user != null)
                {
                    // Set SID
                    users[x].UserId = user.Sid.ToString();
                }
            }

        }
        // Get only users that was matched with their username in the AD
        var usersWithSid = users.Where(u => u.UserId != null).ToList();
        
        // Pass the users to your update method
        myPersonRepository.UpdateUsers(usersWithSid);
        return users;
    }

What I leave to you is the UpdateUsers method other than that we have just took out the users we found having the same logon name in the AD as in our UserName. Then we pass this list of users into the UpdateUsers method (this does what it says… it updates users). What is the result? Users will have their UserId value changed from NULL to SID.

is now…

not null anymore.

Leave a comment

Your email address will not be published. Required fields are marked *