2017-03-01 2 views
1

모든 로컬 그룹 및 그들의 존중받는 구성원의 모음을 만들려고 노력하고 있습니다. 그러나 나열된 코드에서 "Administrators"그룹 구성원이 비어 있으며 서버의 다른 모든 그룹 관리자가 아닌 구성원을 반환합니다. 어떤 아이디어?로컬 그룹 구성원 나열

private void BuildGroupMembership(string remoteHost, string targetdomain, string userName, string password, bool domainOnly) 
{ 
    var groupsList = new List<string>(); 
    PrincipalContext pContext = null; 
    PrincipalContext searchContext = null; 

    if (string.IsNullOrEmpty(remoteHost)) 
    { 
     remoteHost = Environment.MachineName; 
    } 

    if (!string.IsNullOrEmpty(userName) && !string.IsNullOrEmpty(password)) 
    { 
     pContext = new PrincipalContext(ContextType.Machine, remoteHost, null, ContextOptions.Negotiate, userName, password); 
     searchContext = new PrincipalContext(ContextType.Domain, targetdomain, null, ContextOptions.Negotiate, userName, password); 
    } 
    else 
    { 
     pContext = new PrincipalContext(ContextType.Machine, remoteHost, null, ContextOptions.Negotiate); 
     searchContext = new PrincipalContext(ContextType.Domain, targetdomain, null, ContextOptions.Negotiate); 
    } 
    try 
    { 
     var pSearcher = new PrincipalSearcher(new GroupPrincipal(pContext)); 
     foreach (var principal in pSearcher.FindAll().Where(principal => !groupsList.Contains(principal.Name))) groupsList.Add(principal.Name); 
     foreach (var group in groupsList) 
      try 
      { 
       var groupItem = new Group {GroupName = group}; 
       Groups.Add(groupItem); 
       var grp = GroupPrincipal.FindByIdentity(pContext, group); 
       if (grp != null) 
       { 
        var allmembers = grp.GetMembers(false).ToList(); 
        var members = domainOnly ? allmembers.Where(x => x.ContextType == ContextType.Domain).ToList() : allmembers.ToList(); 
        foreach (var p in members) 
         try 
         { 
          var adGroup = GroupPrincipal.FindByIdentity(searchContext, IdentityType.Sid, p.Sid.Value); 
          if (adGroup != null) 
          { 
           groupItem.GroupMembers.Add(new GroupMember 
           { 
            MemberDomain = adGroup.DistinguishedName.Substring(adGroup.DistinguishedName.IndexOf("DC="), adGroup.DistinguishedName.Length - adGroup.DistinguishedName.IndexOf("DC=")).Replace("DC=", "").Replace(",", "."), 
            MemberName = p.SamAccountName, 
            MemberSID = p.Sid.ToString(), 
            IsGroup = true 
           }); 
           continue; 
          } 
          var adUser = UserPrincipal.FindByIdentity(searchContext, IdentityType.Sid, p.Sid.ToString()); 
          if (adUser != null) 
          { 
           groupItem.GroupMembers.Add(new GroupMember 
           { 
            MemberDomain = adUser.DistinguishedName.Substring(adUser.DistinguishedName.IndexOf("DC="), adUser.DistinguishedName.Length - adUser.DistinguishedName.IndexOf("DC=")).Replace("DC=", "").Replace(",", "."), 
            MemberName = p.SamAccountName, 
            MemberSID = p.Sid.ToString(), 
            IsGroup = false 
           }); 
          } 
         } 
         catch 
         { 
          // ignored 
         } 
        grp.Dispose(); 
       } 
      } 
      catch 
      { 

      } 
     pContext.Dispose(); 
     searchContext.Dispose(); 
    } 
    catch (COMException ex) 
    { 
     throw new AuthenticationException(ex.Message); 
    } 
} 

답변

0

이 질문에 대한 답변은 완전하지 않지만 도움이됩니다. WMI를 사용하면 PrincipalContext을 사용하는 것보다 훨씬 빠릅니다 (적어도 제 경우에는). 내 응용 프로그램에서만 필요한 경우 관리자 및 사용자.

static Regex partComponentRegex = new Regex("^[^:]+:Win32_UserAccount.Domain=\"(?<Domain>.+?)\",Name=\"(?<Name>.+?)\"$"); 

static IEnumerable<User> GetUsersFromSidType(WellKnownSidType wellKnownSidType) 
{ 
    string gName = GetGroupName(wellKnownSidType); 
    using (ManagementObjectSearcher groupSearcher = new ManagementObjectSearcher(
     string.Format("SELECT * FROM Win32_GroupUser WHERE GroupComponent =\"Win32_Group.Domain='{0}',Name='{1}'\"", 
     Environment.MachineName, 
     gName))) 
    { 

     foreach (var group in groupSearcher.Get()) 
     { 
      Match m = partComponentRegex.Match(group["PartComponent"].ToString()); 
      if (m.Success) 
      { 
       using (ManagementObjectSearcher userSearcher = new ManagementObjectSearcher(
        string.Format("SELECT * FROM Win32_UserAccount WHERE Name='{0}' AND Domain='{1}'", 
        m.Groups["Name"], m.Groups["Domain"]))) 
       { 
        foreach (var user in userSearcher.Get()) 
        { 
         yield return new User() 
         { 
          Disabled = (bool)user["Disabled"], 
          Domain = user["Domain"].ToString(), 
          FullName = user["FullName"].ToString(), 
          Name = user["Name"].ToString(), 
          SID = user["SID"].ToString() 
         }; 
        } 
       } 
      } 
     } 
    } 
} 

static string GetGroupName(WellKnownSidType wellKnownSidType) 
{ 
    SecurityIdentifier sid = new SecurityIdentifier(wellKnownSidType, null); 
    using (ManagementObjectSearcher searcher = new ManagementObjectSearcher(
     string.Format("SELECT * FROM Win32_Group WHERE SID='{0}'", 
     sid.Value))) 
    { 
     var e = searcher.Get().GetEnumerator(); 
     if (e.MoveNext()) 
      return e.Current["Name"].ToString(); 
     return null; 
    } 
} 
관련 문제