开发者

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

开发者 https://www.devze.com 2023-01-17 17:59 出处:网络
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

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 and the users of the AD groups that are contained. Do you know a solution for this with a good performance?


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


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

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


You can use powershell to solve this.

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.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号