Search code examples
c#active-directoryldapdirectoryservicesdirectorysearcher

Unable to get Changes Using uSNChanged


I want to get incremental changes from Active Directory using C#. And for that I am trying to build a solution as mentioned in the following article.

https://learn.microsoft.com/en-us/windows/win32/ad/polling-for-changes-using-usnchanged

However, I am facing following problems:

  1. There is no uSNChanged property available for user (although it is available for OU i.e. OrganizationalUnit). I can see only following properties for user.

enter image description here

  1. When I am moving users from OU1 to OU2, then highestcommittedusn get incremented but when I am querying for changes (search.Filter = "(uSNChanged>=13000)") using following code, I DO NOT get any updates.

  2. same case is for adding a user inside an OU.

Sample Code is mentioned below:

public static void GetUpdates()
{
    var myLdapConnection = createDirectoryEntry();
    var search = new DirectorySearcher(myLdapConnection);
    search.Filter = "(uSNChanged>=13000)";
    search.SearchScope = System.DirectoryServices.SearchScope.Subtree;
    var results = search.FindAll();
    Console.WriteLine(results.Count);
}

public static DirectoryEntry createDirectoryEntry()
{
    DirectoryEntry ldapConnection = new DirectoryEntry("LDAP://adfs.fed.abcd.com/DC=adfs,DC=fed,DC=abcd,DC=com");
    ldapConnection.Path = "adfs.fed.abcd.com";
    ldapConnection.AuthenticationType = AuthenticationTypes.Secure;
            return ldapConnection;
}

 private static long GetHighestUsn()
 {
     using (LdapConnection connection = new LdapConnection(ldapPath))
     {
          var filter = "(&(objectClass=*))";
          var searchRequest = new SearchRequest(null, filter, System.DirectoryServices.Protocols.SearchScope.Base, "highestCommittedUSN");
          var response = connection.SendRequest(searchRequest) as SearchResponse;
          var usn = response.Entries[0].Attributes["highestcommittedusn"][0];
          return Convert.ToInt64(usn);
      }
      return 0;
}

Any help is highly appreciated.

Edit:

  1. I have only ONE domain controller.

Solution

  • Answer: The code was correct.

    I needed to provide "Read all user information" permission to the user (which was making the request) and after that I starting getting usnchanged property with every object including user.

    Steps to enable permission is given in below article. https://social.technet.microsoft.com/Forums/en-US/b34f7295-4989-4440-93af-cebd6d66c711/cannot-read-the-usnchanged-attribute-for-some-users-why?forum=winserverDS