2017-03-01 24 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; 
    } 
} 
関連する問題