列出本地组成员

时间:2017-03-01 17:10:09

标签: c# group-membership groupprincipal

我正在尝试构建所有本地组及其受尊敬成员的集合,但是我对列出的代码所带来的挑战是“管理员”组成员是空的,服务器上的所有其他组只返回其成员不是管理员。任何想法?

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);
    }
}

1 个答案:

答案 0 :(得分: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;
    }
}