Перечисление вложенных групп пользователей AD с использованием C#
Я написал некоторый код, который получает всех пользователей групп и вложенных групп. Я также хотел убедиться, что зацикливание не произойдет, если членство в группе вызвало зацикливание, если первая группа является членом последней группы.
Код, который я написал, работает хорошо, но немного медленно.
Это первый раз, когда я пытался сделать поиск AD.
Может ли кто-нибудь взглянуть и сказать мне, выглядит ли код нормально или плохо (или хуже), или я ошибся?
using System;
using System.Collections.Generic;
using System.Text;
using System.DirectoryServices;
using System.IO;
namespace Tester3
{
class Program3
{
public static List<string> appGroupList = new List<string>();
public static List<string> userList = new List<string>();
public static List<string> groupList = new List<string>();
public static List<string> groupChecked = new List<string>();
static void Main(string[] args)
{
// Create Output File
StreamWriter outputfile = new StreamWriter("output.txt", false);
appGroupList.Add("GLB-SBCCitrixHelpdesk-DL");
appGroupList.Add("SBC_UKBSAVIA001_PROD_ROL_Siebel");
foreach (string appGroup in appGroupList)
{
string appGroupCN = GetCN(appGroup);
GetMembers(appGroupCN);
groupChecked.Clear();
}
foreach (string item in userList)
{
Console.WriteLine(item);
outputfile.WriteLine(item);
}
outputfile.Flush();
outputfile.Close();
Console.ReadLine();
}
private static string GetCN(string group)
{
string groupCN = string.Empty;
try
{
using (DirectorySearcher search = new DirectorySearcher())
{
search.Filter = "(&(cn=" + group + ")(objectClass=group))";
search.PropertiesToLoad.Add("CN");
SearchResult result = search.FindOne();
if (result != null)
{
groupCN = result.Properties["adsPath"][0].ToString();
groupCN = groupCN.Replace("LDAP://", "");
}
return groupCN;
}
}
catch (Exception)
{
return groupCN;
}
}
public static void GetMembers(string group) // get members using the groups full cn
{
// Check if group has already been checked
if (groupChecked.Contains(group))
{
return;
}
// Add group to groupChecked list
groupChecked.Add(group);
try
{
// Connect to group object
using (DirectoryEntry groupObject = new DirectoryEntry("LDAP://" + group))
{
// Get member of group object
PropertyValueCollection col = groupObject.Properties["member"] as PropertyValueCollection;
// Loop through each member
foreach (object member in col)
{
// Connect to member object
using (DirectoryEntry memberObject = new DirectoryEntry("LDAP://" + member))
{
// Get class of member object
string memberClass = memberObject.Properties["objectClass"][1].ToString();
string memberCN = memberObject.Properties["Name"][0].ToString();
if (!groupChecked.Contains(member.ToString()))
{
if (memberClass.ToLower() == "group")
{
GetMembers(member.ToString());
}
else
{
userList.Add(memberCN);
}
}
else
{
if (memberClass.ToLower() != "group")
{
userList.Add(memberCN);
}
}
}
}
}
}
catch (Exception)
{
}
}
}
}
1 ответ
Если вы используете.NET 3.5 и выше, вы должны проверить System.DirectoryServices.AccountManagement
(S.DS.AM) пространство имен. Прочтите все об этом здесь:
- Управление принципами безопасности каталогов в.NET Framework 3.5
- Документы MSDN на System.DirectoryServices.AccountManagement
По сути, вы можете определить контекст домена и легко найти пользователей и / или группы в AD:
// set up domain context
PrincipalContext ctx = new PrincipalContext(ContextType.Domain);
// find a user
UserPrincipal user = UserPrincipal.FindByIdentity(ctx, "SomeUserName");
if(user != null)
{
// get a user's group memberships
foreach(Principal principal in me.GetGroups())
{
GroupPrincipal gp = (principal as GroupPrincipal);
if(gp != null)
{
// do something with the group
}
}
}
Новый S.DS.AM позволяет очень легко играть с пользователями и группами в AD. Призыв к .GetGroups()
также решает все проблемы, связанные с членством во вложенных группах и т. д. - вам больше не нужно с этим сталкиваться!