Please note: This is a rewrite of an article I wrote way back in 2007. The original article has been updated with a link to this one.

As per usual I had a situation where I had to do some Active Directory stuff with VB.NET. I had to grab a list of all the users in our AD so that people could select a user and perform functions on them from within a webpage.
Another note: This article is VB.NET-specific. If you’d like to know how to do this using C# please see this post’s “partner” entitled “Follow Up – List active directory users – This time in C#”

Carrying on though, there are a number of ways you can do this but in the .NET Framework they all involve using the System.DirectoryServices namespace. A couple of quick things to be aware of before you try this yourself:

  • Before messing with your Active Directory make sure you know what you’re doing and have the permissions of your AD Administrators (if it’s not you!)
  • If you are going to use any of the following code from a .NET console application you’ll need to add a reference to System.DirectoryServices in addition to importing the namespace. I wrote a post a while ago about this entitled “Developer Dumbness” – it has the steps you need to add a reference to a .NET console application.

Anyway, the code below is a simple function that queries your Active Directory domain and retrieves all the user objects. This particular example filters out any user account whose “DisplayName” attribute meets the following criteria (the requirements for the app I had to write):

  • Has an email address
  • Does not contain the “$” symbol
  • Does not contain the words “Admin” or “admin”
  • Does not contain the words “Test” or “test”
  • Does not contain the words “Service” or “service”
  • Does not contain the word “System” or “system”

The example code below is a complete Windows console application that does all of the above. It’s important to note that if you’re using this in a production environment you’ll need to make sure the application containing the code has access to the Active Directory, usually using .NET impersonation – this is beyond the scope of this post.

List Active Directory Users in VB.NET:
[code lang=”vb”]
Imports System
Imports System.Collections.Generic
Imports System.DirectoryServices

Module ListAdUsers

Sub Main(ByVal ParamArray Args() As String)

Console.Clear()
Dim userList As List(Of String) = New List(Of String)

Dim badEntries As Integer = 0
Dim domainName As String = String.Empty

If (Args.Length > 0) Then
domainName = Args(0)
Else
Console.Write(String.Format("{0}Please enter your Active Directory domain name: ", vbCrLf))
domainName = Console.ReadLine()
End If

Console.Write(String.Format("{0}Attempting to build user list for {1} …{0}{0}", vbCrLf, domainName))

Try
If Not String.IsNullOrEmpty(domainName) Then
Dim myDirectoryEntry As DirectoryEntry = New DirectoryEntry(String.Format("LDAP://{0}", domainName))
Dim mySearcher As DirectorySearcher = New DirectorySearcher(myDirectoryEntry)
Dim mySort As SortOption = New SortOption("sn", SortDirection.Ascending)
mySearcher.Filter = ("(objectClass=user)")
mySearcher.Sort = mySort
For Each resEnt As SearchResult In mySearcher.FindAll()
Try
If Not String.IsNullOrEmpty(resEnt.Properties("Mail")(0).ToString()) _
AndAlso System.Text.RegularExpressions.Regex.IsMatch(resEnt.Properties("DisplayName")(0).ToString(), " |admin|test|service|system|[$]", System.Text.RegularExpressions.RegexOptions.IgnoreCase) Then
Dim space As Integer = resEnt.Properties("DisplayName")(0).ToString().IndexOf(" ")
Dim formattedName As String = String.Format("{0}{1}{2}", _
resEnt.Properties("DisplayName")(0).ToString().Substring(space).PadRight(25), _
resEnt.Properties("DisplayName")(0).ToString().Substring(0, space).PadRight(15), _
resEnt.Properties("Mail")(0).ToString() _
)
userList.Add(formattedName)
End If
Catch
badEntries = badEntries + 1
End Try
Next
If (userList.Count > 0) Then
Console.WriteLine(String.Format("=========== Listing of users in the {0} domain{1}", domainName, vbCrLf))
Console.WriteLine(String.Format("{0}{1}{2}{3}", "Surname".PadRight(25), "First Name".PadRight(15), "Email Address", vbCrLf))
For i = 0 To userList.Count – 1
Console.WriteLine(userList(i).ToString())
Next
Console.WriteLine(String.Format("{0}=========== {1} users found in the {2} domain", vbCrLf, userList.Count.ToString(), domainName))
Else
Console.WriteLine(String.Format("{0}=========== 0 users found in the {1} domain", vbCrLf, userList.Count.ToString()))
End If
Console.WriteLine(String.Format("=========== {0} objects could not be read", badEntries.ToString()))
Console.WriteLine("=========== End of Listing")
Else
Console.WriteLine("Please enter a domain name next time!")
End If
Catch ex As Exception
‘ in a production app you wouldn’t show the user the exception details
Console.Write(String.Format("A critical error occurred.{0}Details: {1}", vbCrLf, ex.Message.ToString()))
End Try
End Sub

End Module
[/code]

There are a HEAP of attributes you can use instead of “sn” in the sample above. Personally I use ADSIEDIT.MSC to look at all the possible attributes but you’ll need domain administrative access to run that. Here are a couple of useful ones though …

  • company
  • department
  • description
  • displayName
  • mail
  • manager
  • name
  • givenName
  • sAMAccountName

Hope that helps someone! 🙂