.NET Find deleted users in Active Directory

Posted by Klavs Reinfelds on February 18, 2017 · 2 mins read

How to find deleted users?

To find deleted Active Directory objects, you need to use attribute isDeleted and filter only true values. And to filter only user objects, you need to use this LDAP filter - (sAMAccountType=805306368).

[code lang="csharp"]
using (DirectoryEntry entry = new DirectoryEntry("LDAP://YourADDomain.com"))
{
  using (DirectorySearcher searcher = new DirectorySearcher(entry))
  {
    searcher.Filter = "(&(sAMAccountType=805306368)(isDeleted=true))";
    searcher.Tombstone = true;
    SearchResultCollection users = searcher.FindAll();
    foreach (SearchResult user in users)
    {
      //process deleted user
    }
  }
}
[/code]

This filter doesn't return any deleted users!?

The problem is in the filter when an object gets deleted, then many attributes are deleted from it. So deleted user objects don't have sAMAccountType attribute. We can try to use objectClass attribute. Filter would look like this (&(objectCategory=person)(objectClass=user)) according to Microsoft site example.

New filter

(&(objectClass=user)(objectClass=person)(isDeleted=true))

After testing this new filter, I found out that computer objects are too in this list. According to Microsoft site, possible objectClass combinations are:

objectCategory objectClass Result
person user user objects
person   user and contact objects
person contact contact objects
  user user and computer objects
computer   computer objects
user   user and contact objects
  contact contact objects
  computer computer objects
  person user, computer, and contact objects
contact   user and contact objects
group   group objects
  group group objects
person organizationalPerson user and contact objects
  organizationalPerson user, computer, and contact objects
organizationalPerson   user and contact objects

Final version

This is the final working version, that returns all deleted user objects.

[code lang="csharp"]
using (DirectoryEntry entry = new DirectoryEntry("LDAP://YourADDomain.com"))
{
  using (DirectorySearcher searcher = new DirectorySearcher(entry))
  {
    searcher.Filter = "(&(objectClass=user)(objectClass=person)(!(objectClass=computer))(isDeleted=true))";
    searcher.Tombstone = true;
    SearchResultCollection users = searcher.FindAll();
    foreach (SearchResult user in users)
    {
      //process deleted user
    }
  }
}
[/code]

References

https://social.technet.microsoft.com/wiki/contents/articles/5392.active-directory-ldap-syntax-filters.aspx