【问题标题】:c# GroupPrincipal.FindByIdentity finds the group, but when using GetMembers getting error - there is no such object on the serverc# GroupPrincipal.FindByIdentity 找到组,但是使用 GetMembers 时出错 - 服务器上没有这样的对象
【发布时间】:2018-08-27 10:15:49
【问题描述】:

这段代码过去一年运行良好, 现在它仍在工作,但我只有 4 个组会产生此错误...

代码很简单:

   using (var context = new PrincipalContext(ContextType.Domain, domName))
              {
                  foreach (string grp in myGroups)
                  {
                      using (var group = GroupPrincipal.FindByIdentity(context, IdentityType.Name, grp))
                      {
                          PrincipalSearchResult<Principal> usersList;

                          usersList = group.GetMembers(true);

                          int usersListCount = usersList.Count();
}}}

当这些特定的组来搜索时,我得到了组并且可以在组对象变量中看到它的描述,但是当得到它的成员时我得到一个错误消息:

base: "服务器上没有这样的对象。\r\n"

错误代码:-2147016656

再次,这种情况发生在来自同一域和同一 OU 的 4 个特定组中。 这只是几天前才开始的,我没有更改任何内容,没有权限,代码中没有任何内容,很奇怪......

有什么想法吗?

【问题讨论】:

  • 不,没有......

标签: c# active-directory ldap-query principalcontext groupprincipal


【解决方案1】:

当我遇到这个问题时,我不能有一个空组。当网络人员正在努力解决“外国 SID”问题时,我必须产生“可能的最佳”结果。 我知道这是很多额外的,但它让审计员满意,所以也许它会对你有所帮助。这就是我所做的:

  1. 前体:我已经构建了一个包含 AD 实体所有属性的类。
  2. 获得了用户列表及其所有组成员身份。
  3. 将获取成员的调用包装在 try...catch 中,当发生此错误时,我插入了“检索成员错误”的“组成员身份”属性
  4. 当我遍历所有组时,我获取了作为组成员包含错误消息的所有组的列表,然后查询用户列表以获取作为该组成员的所有用户的列表。
  5. 然后用找到的用户名插入属性记录。

由于这个答案更多的是关于解决方案结构,我只会简要介绍所使用的类。虽然远非优雅,但它给了我一个易于理解和共享的可重用容器,并提供了一个在多个网络中持久的解决方案。它可能在很多方面都缺乏,但它通过了测试 #1 - 它有效。

public class ADPropEntry : IComparable<ADPropEntry>
{
        #region Properties
        public string Name { get { return _name; } set { _adName = value; SetPropVals(_adName); } }
        public string Value { get { return _v; } set { _v = value; DoValConversion(); } }
        public bool IsVisible { get { return _isVis; } set { _isVis = value; } }
        public string ConvertTo { get { return _convertVal; } set { _convertVal = value; } }
        public int ID { get { return _id; } set { _id = value; } }
        #endregion

        private void SetPropVals(string s)
        {
            switch (s)
            {
                case "accountexpires": _name = "Account Expires"; _isVis = false; _convertVal = "FromFileTime"; break;
                ... more handles each property conversion
            }
        }
    }
    public class ADEntity : IComparable<ADEntity>
    {
        #region Properties
        public string Name { get { return _name; } set { _name = value; } }
        public List<ADPropEntry> MyProperty { get { return _ade; } set { _ade = value; } }
        public string EntityType { get { return _entT; } set { _entT = value; } }
        public string ADName { get { return GetProperty("SAM Account Name"); } }
        #endregion
    }

这种形式为我提供了一个持久的数据容器,然后我使用另一个类以任何有意义的方法查询 AD。这被打包在客户端应用程序可以使用的 DLL 中。

    class ADAccess
    {
        #region Properties
        public bool HasErrors { get { return (bool)(_errMsg.Length > 10); } }
        public string ErrorMsg { get { return _errMsg; } }
        public List<ADEntity> GroupEntries { get { return _lstGrps; } }
        public List<ADEntity> UserEntries { get { return _lstUsrs; } }
        public List<ADEntity> PrinterEntries { get { return _lstPrts; } }
        public List<ADEntity> ComputerEntries { get { return _lstCmps; } }
        #endregion
    
    public List<ADEntity> GetADListByMSO(string groupType)
    {
        if (groupType == "")
        {
             // get them all return an empty list populating properties
        }
        else
        {
             // set the context and fetch return populated list
        }
    }

也使用相同的结构来报告 SQL 服务器权限。

【讨论】:

    【解决方案2】:

    我发现了问题, 问题组包含来自不同域的用户, 从组中删除这些用户后,一切都恢复正常。 谢谢。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-12-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-25
      • 1970-01-01
      相关资源
      最近更新 更多