5

我正在使用System.DirectoryServices.AccountManagement命名空间类来管理多个组的成员资格。这些团体控制着我们印刷会计系统的人口,其中一些非常庞大。我在从这些大型组之一中删除任何用户时遇到了问题。我有一个说明问题的测试程序。请注意,我正在测试的组不是嵌套的,但 user.IsMemberOf() 似乎也有同样的问题,而 GetAuthorizationGroups() 正确显示了用户所属的组。有问题的组有大约 81K 成员,这比它应该拥有的多,因为 Remove() 不起作用,通常约为 65K 左右。

我很想听听其他遇到此问题并已解决的人的意见。我有一个微软的未结案子,但由于呼叫中心大约有 17 小时的时差,所以他们在我通常离开家前大约一个小时才到公司上班。

using (var context = new PrincipalContext( ContextType.Domain ))
{
    using (var group = GroupPrincipal.FindByIdentity( context, groupName ))
    {
        using (var user = UserPrincipal.FindByIdentity( context, userName ))
        {
            if (user != null)
            {
                var isMember = user.GetAuthorizationGroups()
                                   .Any( g => g.DistinguishedName == group.DistinguishedName );
                Console.WriteLine( "1: check for membership returns: {0}", isMember );
                if (group.Members.Remove( user ))
                {
                    Console.WriteLine( "user removed successfully" );
                    group.Save();
                }
                else
                {
                    // do save in case Remove() is lying to me
                    group.Save();
                    Console.WriteLine( "user remove failed" );
                    var isStillMember = user.GetAuthorizationGroups()
                                            .Any( g => g.DistinguishedName == group.DistinguishedName );
                    Console.WriteLine( "2: check for membership returns: {0}", isStillMember );

                }
            }
        }
    }
}
4

3 回答 3

5

原来这是 GroupPrincipal.Members.Remove() 代码中的一个错误,其中对于超过 1500 个成员的组,删除失败。这已在 .NET 4.0 Beta 2 中修复。我不知道他们是否有计划将修复移植到 2.0/3.x 中。

解决方法是获取底层 DirectoryEntry,然后使用 Invoke 对 IADsGroup 对象执行 Remove 命令。

 var entry = group.GetUnderlyingObject() as DirectoryEntry;
 var userEntry = user.GetUnderlyingObject() as DirectoryEntry;
 entry.Invoke( "Remove", new object[] { userEntry.Path } );
于 2009-12-11T15:33:42.803 回答
1

这篇文章帮助我指出了正确的方向,只是想添加一些附加信息。

它还可以直接绑定到组,您可以使用它来添加组成员。

using (var groupEntry = new DirectoryEntry(groupLdapPath))
{
    groupEntry.Invoke("remove", new object[] { memberLdapPath });
    groupEntry.Invoke("add",    new object[] { memberLdapPath });
}

另请注意,使用标准的“成员”属性,您使用用户或组的专有名称,但调用需要带有 LDAP:// 前缀的路径,否则会引发模糊的 InnerException:

Exception from HRESULT: 0x80005000
于 2014-08-20T10:42:30.397 回答
0
public bool RemoveUserFromGroup(string UserName, string GroupName)
{
   bool lResult = false;
   if (String.IsNullOrEmpty(UserName) || String.IsNullOrEmpty(GroupName)) return lResult;
   try
   {
      using (DirectoryEntry dirEntry = GetDirectoryEntry())
      {
         using (DirectoryEntry dirUser = GetUser(UserName))
         {
            if (dirEntry == null || dirUser == null)
            {
               return lResult;
            }
            using (DirectorySearcher deSearch = new DirectorySearcher())
            {
               deSearch.SearchRoot = dirEntry;
               deSearch.Filter = String.Format("(&(objectClass=group) (cn={0}))", GroupName);
               deSearch.PageSize = 1000;
               SearchResultCollection result = deSearch.FindAll();
               bool isAlreadyRemoved = false;
               String sDN = dirUser.Path.Replace("LDAP://", String.Empty);
               if (result != null && result.Count > 0)
               {
                  for (int i = 0; i < result.Count; i++)
                  {
                     using (DirectoryEntry dirGroup = result[i].GetDirectoryEntry())
                     {
                        String sGrDN = dirGroup.Path.Replace("LDAP://", String.Empty);
                        if (dirUser.Properties[Constants.Properties.PROP_MEMBER_OF].Contains(sGrDN))
                        {
                           dirGroup.Properties[Constants.Properties.PROP_MEMBER].Remove(sDN);
                           dirGroup.CommitChanges();
                           dirGroup.Close();
                           lResult = true;
                           isAlreadyRemoved = true;
                           break;
                        }
                     }
                     if (isAlreadyRemoved)
                        break;
                  }
               }
            }
         }
      }
   }
   catch
   {
      lResult= false;
   }
   return lResult;
}
于 2014-02-06T18:08:37.810 回答