今天早上,我开始注意到我的几个程序在 Active Directory 读取操作方面存在一些问题。我注意到所有这些应用程序(客户端和服务器)都使用 System.DirectoryServices.AccountManagement.UserPrincipal 类进行这些读取操作,而程序仍在正确运行时使用 System.DirectoryServices.DirectorySearcher

所以为了解决这个问题,我构建了以下非常简单的控制台应用程序

class Program
{
    static void Main(string[] args)
    {
        //this works great
        Console.WriteLine($"Enviroment.Username:{Environment.UserName}");

        //this works great
        PrincipalContext pcFull = new PrincipalContext(ContextType.Domain, "my.company.de", "dc=my,dc=company,dc=de");
        UserPrincipal upPrincipalContextFull = UserPrincipal.FindByIdentity(pcFull, Environment.UserName);

        //this doesn't work at all
        //Exception: “The specified directory service attribute or value does not exist”
        PrincipalContext pc = new PrincipalContext(ContextType.Domain);
        UserPrincipal upPrincipalContext = UserPrincipal.FindByIdentity(pc, Environment.UserName);

        //this doesn't either, same exception
        UserPrincipal upCurrent = UserPrincipal.Current;

        Console.ReadKey();
    }
}

正如您在评论中看到的那样,后两个操作将在我测试过的域中的每台计算机上失败,即使它们完美地工作了几年。当我调用 UserPrincipal.CurrentUserPrincipal.FindByIdentity(pc, Environment.UserName); 而没有在 PrincipalContext 中指定容器时,会发生以下异常:
System.Runtime.InteropServices.COMException: “The specified directory service attribute or value does not exist”
这是我所知道的:
  • 突然停止工作的应用程序在过去两周内均未收到更新
  • 所有这些应用程序,UserPrincipal.Current -Property 和 UserPrincipal.FindByIdentity -Method 昨天完美运行
  • 工作站在上周未收到 Windows 或 .Net 更新
  • 该现象与单个工作站、用户或操作系统无关,而是发生在运行 Windows 7 或 10 的许多不同机器上的许多不同用户上。
  • 域 Controller 一周前收到更新。显然,这些更新之一有一个关于 LDAP 查询的已知问题: Due to a defect in WLDAP32.DLL, applications that perform LDAP referral chasing can consume too many dynamic TCP ports 。这似乎不太可能是突然失败的原因,因为 a) 该补丁是一周前安装的,而问题仅在今天发生,并且 b) Microsoft 建议的解决方法(重新启动服务)没有任何影响

  • 如果您知道什么可能导致“一夜之间”出现这种行为,请与我分享。如果它真的与 Windows 更新有关,其他用户很快也会遇到此错误!

    我显然可以构建变通方法,所以我不必使用失败的方法和属性,但我仍然必须首先知道它为什么停止工作。

    编辑: 首先,了解两者之间的区别会很有用public PrincipalContext(ContextType contextType);public PrincipalContext(ContextType contextType, string name, string container);
    没有容器构造的 PrincipalContext 仍然必须以某种方式获取该容器,不是吗?

    另外,如果您不赞成我的问题,那么知道为什么会很高兴。否则很难改进;)

    最佳答案

    默认情况下,PrincipalContext 在“OU=Computers”-Container 中搜索。
    如果未为 Container 设置读取权限,则此操作将失败,并将引发 COM 异常。

    10-07 19:40
    查看更多