【发布时间】:2017-02-11 13:57:31
【问题描述】:
我一直在寻找解决方案,但我找到的所有解决方案都很慢。 我想获取本地 Windows 组中的所有用户。这个组当然也可以包含 AD 组。因此,结果应该包含属于组本身的所有用户和所包含的 AD 组的用户。 您知道性能良好的解决方案吗?
【问题讨论】:
我一直在寻找解决方案,但我找到的所有解决方案都很慢。 我想获取本地 Windows 组中的所有用户。这个组当然也可以包含 AD 组。因此,结果应该包含属于组本身的所有用户和所包含的 AD 组的用户。 您知道性能良好的解决方案吗?
【问题讨论】:
你试过了吗,这个示例在你的本地机器上获取管理员组成员
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;
}
}
【讨论】:
嘿,前段时间我做了一组类来做这件事,但它是基于域而不是组的:)
这里是课程。有一个 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; }
}
【讨论】:
你可以使用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
}
}
从这样的文件中读取计算机:
$computers = Get-Content $Global:ComputersFile
$AllComputerMembers = GetLocalArray -ComputerArray $computers
从这里您可以使用 convertto-csv、export-csv、convertto-json 在 Web 或 Excel 上使用它。
【讨论】: