windows 如何获得本地组中的所有用户(性能良好)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3774072/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 15:17:51  来源:igfitidea点击:

How can I get all users in a local group (with good performance)

c#windows

提问by Rocko

I looking for a solution for quite while but all solutions I found are very slow. I want to get all users in local windows group. This group can of course also contain AD groups. So the result should contain all users that are members of the group itself andthe users of the AD groups that are contained. Do you know a solution for this with a good performance?

我一直在寻找解决方案,但我找到的所有解决方案都很慢。我想获取本地 Windows 组中的所有用户。该组当然也可以包含 AD 组。所以结果应该包含对组本身的成员的所有用户所包含的AD组的用户。您知道性能良好的解决方案吗?

回答by Raymund

Have you tried this, this sample gets the administrators group members in your local machine

您是否尝试过此操作,此示例获取本地计算机中的管理员组成员

using System;
using System.DirectoryServices.AccountManagement;
using System.Collections;

class Program
{
    static void Main(string[] args)
    {
        ArrayList myGroups = GetGroupMembers("Administrators");
        foreach (string item in myGroups)
        {
            Console.WriteLine(item);
        }
        Console.ReadLine();
    }

    public static ArrayList GetGroupMembers(string sGroupName)
    {
        ArrayList myItems = new ArrayList();
        GroupPrincipal oGroupPrincipal = GetGroup(sGroupName);

        PrincipalSearchResult<Principal> oPrincipalSearchResult = oGroupPrincipal.GetMembers();

        foreach (Principal oResult in oPrincipalSearchResult)
        {
            myItems.Add(oResult.Name);
        }
        return myItems;
    }

    public static GroupPrincipal GetGroup(string sGroupName)
    {
        PrincipalContext oPrincipalContext = GetPrincipalContext();

        GroupPrincipal oGroupPrincipal = GroupPrincipal.FindByIdentity(oPrincipalContext, sGroupName);
        return oGroupPrincipal;
    }

    public static PrincipalContext GetPrincipalContext()
    {
        PrincipalContext oPrincipalContext = new PrincipalContext(ContextType.Machine);
        return oPrincipalContext;
    }

}

http://anyrest.wordpress.com

http://anyrest.wordpress.com

回答by TerrorAustralis

Hey, i made a set of classes to do this a while back, but it got them based on Domain instead of group :)

嘿,不久前我制作了一组类来执行此操作,但是它基于域而不是组来获取它们:)

Here is the classes. There is a userManager class and a User class

这里是课程。有一个 userManager 类和一个 User 类

public class UserManager
{
    private string _domainName;
    private Dictionary<string, User> _userLookup;
    private PrincipalContext domainContext;
    private DirectoryEntry LDAPdirectory;

    public UserManager(string domainName)
    {
        _domainName = domainName;
        _userLookup = new Dictionary<string, User>();
        domainContext = new PrincipalContext(ContextType.Domain, _domainName);
        //Make the LDAP directory look for all users within the domain. DC Com, Au for australia
        LDAPdirectory = new DirectoryEntry("LDAP://DC=" + _domainName.ToLower() + ",DC=com,DC=au");
        LDAPdirectory.AuthenticationType = AuthenticationTypes.Secure;
    }


    public IEnumerable<User> Users
    {
        get
        {
            return _userLookup.Values.ToArray<User>();
        }
        set
        {
            _userLookup.Clear();
            foreach (var user in value)
            {
                if (!_userLookup.ContainsKey(user.Login))
                    _userLookup.Add(user.Login, user);
            }
        }
    }

    /// <summary>
    /// Gets all the users from the AD domain and adds them to the Users property. Returns the list.
    /// </summary>
    /// <returns></returns>
    public IEnumerable<User> UpdateAllUsers()
    {

        DirectorySearcher searcher = new DirectorySearcher(LDAPdirectory);
        searcher.Filter = "(&(&(objectClass=user)(objectClass=person)(!objectClass=computer)(objectClass=organizationalPerson)(memberof=*)(telephonenumber=*)))";

        SearchResultCollection src = searcher.FindAll();
        _userLookup.Clear();

        foreach (SearchResult result in src)
        {
            User newUser = new User(domainContext, result.Properties["samaccountname"][0].ToString());

            if (newUser.IsInitialized)
            {
                _userLookup.Add(newUser.Login, newUser);
                yield return newUser;
            }
        }



    }
    public User GetUser(string userLogin)
    {
        return new User(domainContext, userLogin);
    }

    public bool HasUser(string login)
    {
        return _userLookup.ContainsKey(login);
    }
}

public class User
{
    public User()
    {
        IsInitialized = false;
    }
    /// <summary>
    /// Initializes a new user based on the AD info stored in the domain    
    /// </summary>
    /// <param name="domainContext">The domain to search for this user</param>
    /// <param name="userName">The user to look for</param>
    public User(PrincipalContext domainContext, string userName)
    {
        try
        {
            using (UserPrincipal thisUserPrincipal = UserPrincipal.FindByIdentity(domainContext, userName))
            {
                this.FirstName = thisUserPrincipal.GivenName;
                this.Surname = thisUserPrincipal.Surname;
                this.DisplayName = thisUserPrincipal.DisplayName;
                this.Email = thisUserPrincipal.EmailAddress;
                this.ContactNumber = thisUserPrincipal.VoiceTelephoneNumber;
                this.Login = thisUserPrincipal.SamAccountName;
                IsInitialized = true;
            }
        }
        catch (Exception)
        {
            IsInitialized = false;
            return;
        }
    }
    /// <summary>
    /// Gets a value determining if this user was properly initialized or if an exception was thrown during creation
    /// </summary>
    public bool IsInitialized { get; set; }
    public string FirstName { get; set; }
    public string Surname { get; set; }
    public string DisplayName { get; set; }
    public string Email { get; set; }
    public string Login { get; set; }
    public string ContactNumber { get; set; }
}

回答by Jose Ortega

You can use powershell to solve this.

你可以使用powershell来解决这个问题。

function GetLocalArray{
    [CmdletBinding()]
    param(
         Parameter(ValueFromPipeline=$True,position=0,mandatory=$true)]$ComputerArray
    )
    BEGIN{
       $members=@()
       $filter=@()
    }
 PROCESS{
    foreach($computer in $ComputerArray){
        $gwmiquery = Get-WMIObject win32_group -filter "LocalAccount='True'" -computername $computer #| where{$_.Name -like "*Administrators"} #uncomment to filter the result to just local administrators group
        $gwmiquery | foreach{ 
                $name=$_.Name; 
                $A=$_.GetRelated("Win32_UserAccount").Name -join ";"; #users
                $B=$_.GetRelated("Win32_Account").Name -join ";";    #systemgroup
                $memberUsers =   New-Object PSObject -Property  @{ComputerName=$_.PSComputerName;Name=$name;AllMembers=$B;Members=$A}
                $members+=$memberUsers;
            }
    }
         $filter+= $members | foreach{$name=$_.name; if( ! [String]::IsNullOrWhiteSpace($_.AllMembers)) { $_ }     }
    }
END{
    return $filter
   }
}

Read computers from a file like this:

从这样的文件中读取计算机:

$computers = Get-Content  $Global:ComputersFile
$AllComputerMembers = GetLocalArray -ComputerArray $computers

from here you can use either, convertto-csv, export-csv, convertto-json to use it on web or Excel.

从这里您可以使用 convertto-csv、export-csv、convertto-json 在 Web 或 Excel 上使用它。