es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

No se pueden obtener cambios utilizando uSNChanged.

Quiero obtener cambios incrementales de Active Directory utilizando C#. Para eso, estoy tratando de construir una solución como se menciona en el siguiente artículo.

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

Sin embargo, me enfrento a los siguientes problemas:

1) No hay una propiedad de uSNChanged disponible para el usuario (aunque está disponible para OU, es decir, OrganizationalUnit). Solo puedo ver las siguientes propiedades para el usuario.

Imagen

2) Cuando muevo usuarios de OU1 a OU2, el valor de ‘highestcommittedusn’ se incrementa, pero cuando consulto los cambios (‘search.Filter = “(uSNChanged>=13000)”‘) utilizando el siguiente código, NO obtengo ninguna actualización.

3) El mismo caso ocurre al agregar un usuario dentro de una OU.

El código de muestra se menciona a continuación:

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;
}

Cualquier ayuda es muy apreciada.

Edit:

1) Solo tengo UN controlador de dominio.

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Solución para obtener cambios incrementales desde Active Directory utilizando C

    Si estás enfrentando problemas para obtener cambios incrementales desde Active Directory utilizando C#, sigue los siguientes pasos para resolver el problema:

    1. Verifica que tienes los permisos necesarios para acceder a Active Directory y modificar los atributos de usuario.
    2. Utiliza el siguiente código para obtener el valor USN más alto del dominio:

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

    3. Después de obtener el valor USN más alto, utiliza el siguiente código para obtener los cambios incrementales:
      public static void ObtenerActualizaciones()
      {
         var myLdapConnection = createDirectoryEntry();
         myLdapConnection.SessionOptions.Sealing = true;
         myLdapConnection.SessionOptions.Signing = true;
         myLdapConnection.SessionOptions.ProtocolVersion = 3;
         long currUsn = ObtenerMasAltoUSN() + 1;
         var busqueda = new DirectorySearcher(myLdapConnection);
         busqueda.Filter = $"(&(objectCategory=person)(objectClass=user)(uSNChanged>={currUsn}))";
         busqueda.SearchScope = System.DirectoryServices.SearchScope.Subtree;
         busqueda.NotifySecurityError = false;
         SearchResultsCollection resultados;
         do
         {
             resultados = busqueda.FindAll();
             foreach (SearchResult resultado in resultados)
             {
                 // Procesa cada resultado aquí
             }
             currUsn = ObtenerMasAltoUSN() + 1;
             busqueda.Filter = $"(&(objectCategory=person)(objectClass=user)(uSNChanged>={currUsn}))";
         } while (resultados.Count >= 1);
      }
      

      Este código consultará AD utilizando el atributo ‘uSNChanged’ de los objetos de usuario para obtener cualquier cambio incremental desde la última consulta.

    4. En caso de que no veas el atributo ‘uSNChanged’ para los objetos de usuario, no podrás utilizarlo para cambios incrementales. Puedes utilizar otros atributos como ‘whenChanged’, ‘whenCreated’, etc. para consultar cambios incrementales.

    5. Cuando muevas un usuario de una OU a otra, el atributo ‘uSNChanged’ para ese usuario no se actualizará. Sin embargo, el atributo ‘highestcommittedusn’ para el controlador de dominio se incrementará. Esto significa que necesitas consultar al controlador de dominio para obtener cambios incrementales utilizando el atributo ‘uSNChanged’ de los objetos de usuario.

Comments are closed.