无法使用 uSNChanged 获取更改
Unable to get Changes Using uSNChanged
我想使用 C# 从 Active Directory 获取增量更改。为此,我正在尝试构建一个解决方案,如下文所述。
https://docs.microsoft.com/en-us/windows/win32/ad/polling-for-changes-using-usnchanged
但是,我面临以下问题:
- 没有可供用户使用的 uSNChanged 属性(尽管它可用于 OU,即 OrganizationalUnit)。我只能看到用户的以下属性。
当我将用户从 OU1 移动到 OU2 时,highestcommittedusn
会增加,但是当我使用以下代码查询更改 (search.Filter = "(uSNChanged>=13000)"
) 时,我 不要获取任何更新。
同样的情况是在 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;
}
非常感谢任何帮助。
编辑:
- 我只有一个域控制器。
对于 GetHighestUsn
我认为 new SearchRequest(null ...
中的 null
应该替换为空字符串以获得 RootDSE。
其次你混合System.DirectoryServices
和System.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
我想使用 C# 从 Active Directory 获取增量更改。为此,我正在尝试构建一个解决方案,如下文所述。
https://docs.microsoft.com/en-us/windows/win32/ad/polling-for-changes-using-usnchanged
但是,我面临以下问题:
- 没有可供用户使用的 uSNChanged 属性(尽管它可用于 OU,即 OrganizationalUnit)。我只能看到用户的以下属性。
当我将用户从 OU1 移动到 OU2 时,
highestcommittedusn
会增加,但是当我使用以下代码查询更改 (search.Filter = "(uSNChanged>=13000)"
) 时,我 不要获取任何更新。同样的情况是在 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;
}
非常感谢任何帮助。
编辑:
- 我只有一个域控制器。
对于 GetHighestUsn
我认为 new SearchRequest(null ...
中的 null
应该替换为空字符串以获得 RootDSE。
其次你混合System.DirectoryServices
和System.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