无法使用 uSNChanged 获取更改

Unable to get Changes Using uSNChanged

我想使用 C# 从 Active Directory 获取增量更改。为此,我正在尝试构建一个解决方案,如下文所述。

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

但是,我面临以下问题:

  1. 没有可供用户使用的 uSNChanged 属性(尽管它可用于 OU,即 OrganizationalUnit)。我只能看到用户的以下属性。

  1. 当我将用户从 OU1 移动到 OU2 时,highestcommittedusn 会增加,但是当我使用以下代码查询更改 (search.Filter = "(uSNChanged>=13000)") 时,我 不要获取任何更新。

  2. 同样的情况是在 OU 内添加用户。

示例代码如下:

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

非常感谢任何帮助。

编辑:

  1. 我只有一个域控制器。

对于 GetHighestUsn 我认为 new SearchRequest(null ... 中的 null 应该替换为空字符串以获得 RootDSE。

其次你混合System.DirectoryServicesSystem.DirectoryServices.Protocols:你最好坚持一个。不清楚 new LdapConnection(ldapPath))ldapPath 的值是多少。如果是“adfs.fed.abcd.com”,并且你有多个域控制器,你无法确切知道哪一个会回答,这与最后的评论有关。

最后,USNChanged 属性是非复制属性,这意味着您应该始终请求同一个域控制器来获取更新。另一个域控制器将为同一对象存储完全不同的值。

通常每个对象都应该 return USNChanged 属性,除非您指定了一个有限的属性列表 return,在这种情况下您也必须包含它。

编辑:包括示例代码 (Powershell)

  • System.DirectoryServices
    $entry = [System.DirectoryServices.DirectoryEntry]::new("LDAP://localhost:50005/O=MyAppInstance")
    $entry.psbase.AuthenticationType = [System.DirectoryServices.AuthenticationTypes]::Secure
    $searcher = [System.DirectoryServices.DirectorySearcher]::new($entry)
    $searcher.Filter = "(uSNChanged>=13004)"
    $searcher.SearchScope = [System.DirectoryServices.SearchScope]::Subtree
    $results = $searcher.FindAll()
    $results.Count
  • System.DirectoryServices.协议
    $con = [System.DirectoryServices.Protocols.LdapConnection]::new("localhost:50005")
    $con.AuthType = [System.DirectoryServices.Protocols.AuthType]::Negotiate
    $con.SessionOptions.ProtocolVersion = 3
    $con.Bind()

    $req = [System.DirectoryServices.Protocols.SearchRequest]::new()
    $req.DistinguishedName = "O=MyAppInstance"
    $req.Scope = [System.DirectoryServices.Protocols.SearchScope]::Subtree
    $req.Filter = "(uSNChanged>=13004)"

    $res = [System.DirectoryServices.Protocols.SearchResponse]$con.SendRequest($req)
    $res.Entries.Count

答案:代码正确。

我需要向用户(发出请求的用户)提供“读取所有用户信息”权限,然后我开始对包括用户在内的每个对象进行更改属性。

启用权限的步骤在下面的文章中给出。 https://social.technet.microsoft.com/Forums/en-US/b34f7295-4989-4440-93af-cebd6d66c711/cannot-read-the-usnchanged-attribute-for-some-users-why?forum=winserverDS