C# 如何获取特定用户的所有广告组?

C# 如何获取特定用户的所有广告组?,c#,.net,active-directory,ldap,directoryservices,C#,.net,Active Directory,Ldap,Directoryservices,我已经查过邮件了。但它没有回答我的问题。我想获取特定用户所属的所有active directory组 //Get Direct+Indirect Memberships of User (where SID is XXXXXX) string str = "(& (objectCategory=group)(member:1.2.840.113556.1.4.1941:=<SID=XXXXXX>) )"; //Get Direct+Indirect **Domain Lo

我已经查过邮件了。但它没有回答我的问题。我想获取特定用户所属的所有active directory组

//Get Direct+Indirect Memberships of User (where SID is XXXXXX)

string str = "(& (objectCategory=group)(member:1.2.840.113556.1.4.1941:=<SID=XXXXXX>) )";

//Get Direct+Indirect **Domain Local** Memberships of User (where SID is XXXXXX)

string str2 = "(& (objectCategory=group)(|(groupType=-2147483644)(groupType=4))(member:1.2.840.113556.1.4.1941:=<SID=XXXXXX>) )";

//TAA DAA
我已经编写了以下代码。但我无法继续,因为我不知道如何提供过滤器以及如何访问属性

class Program
{
    static void Main(string[] args)
    {
        DirectoryEntry de = new DirectoryEntry("LDAP://mydomain.com");
        DirectorySearcher searcher = new DirectorySearcher(de);
        searcher.Filter = "(&(ObjectClass=group))";
        searcher.PropertiesToLoad.Add("distinguishedName");
        searcher.PropertiesToLoad.Add("sAMAccountName");
        searcher.PropertiesToLoad.Add("name");
        searcher.PropertiesToLoad.Add("objectSid");
        SearchResultCollection results = searcher.FindAll();
        int i = 1;
        foreach (SearchResult res in results)
        {
            Console.WriteLine("Result" + Convert.ToString(i++));
            DisplayProperties("distinguishedName", res);
            DisplayProperties("sAMAccouontName", res);
            DisplayProperties("name", res);
            DisplayProperties("objectSid", res);
            Console.WriteLine();
        }

        Console.ReadKey();
    }

    private static void DisplayProperties(string property, SearchResult res)
    {
        Console.WriteLine("\t" + property);
        ResultPropertyValueCollection col = res.Properties[property];
        foreach (object o in col)
        {
            Console.WriteLine("\t\t" + o.ToString());
        }
    }
}
有什么想法吗?

使用:

DirectorySearcher ds=newdirectorysearcher();
ds.Filter=String.Format((&(objectClass=user)(sAMAccountName={0})),用户名);
SearchResult sr=ds.FindOne();
DirectoryEntry user=sr.GetDirectoryEntry();
RefreshCache(新字符串[]{“tokenGroups”});
对于(int i=0;i
注意:这只获取安全组

只需查询“memberOf”属性并迭代返回,例如:

            search.PropertiesToLoad.Add("memberOf");
            StringBuilder groupNames = new StringBuilder(); //stuff them in | delimited

                SearchResult result = search.FindOne();
                int propertyCount = result.Properties["memberOf"].Count;
                String dn;
                int equalsIndex, commaIndex;

                for (int propertyCounter = 0; propertyCounter < propertyCount;
                    propertyCounter++)
                {
                    dn = (String)result.Properties["memberOf"][propertyCounter];

                    equalsIndex = dn.IndexOf("=", 1);
                    commaIndex = dn.IndexOf(",", 1);
                    if (-1 == equalsIndex)
                    {
                        return null;
                    }
                    groupNames.Append(dn.Substring((equalsIndex + 1),
                                (commaIndex - equalsIndex) - 1));
                    groupNames.Append("|");
                }

            return groupNames.ToString();
search.PropertiesToLoad.Add(“memberOf”);
StringBuilder groupNames=新建StringBuilder()//把它们塞进|分隔的
SearchResult=search.FindOne();
int-propertyCount=result.Properties[“memberOf”].Count;
字符串dn;
int equalindex,commaIndex;
对于(int-propertyCounter=0;propertyCounter

这只是将组名填充到groupNames字符串中,以管道分隔,但是当您旋转时,您可以对它们执行任何您想要的操作

以下示例来自代码项目文章:

只需使用for the user调用Groups方法,并传入bool标志以指示是否要在生成的ArrayList中包含嵌套/子组成员身份:

ArrayList groups = Groups("LDAP://CN=Joe Smith,OU=Sales,OU=domain,OU=com", true);
foreach (string groupName in groups)
{
    Console.WriteLine(groupName);
}
如果您需要在.NET中进行任何级别的Active Directory编程,我强烈建议您将我上面提到的代码项目文章添加到书签中并进行审阅。

您应该使用。这容易多了。这是一个很好的代码项目,让您概括了解这个DLL中的所有类


正如您所指出的,您当前的方法没有找到主要的组。事实上,这比你想象的要糟糕得多。还有一些情况下它不起作用,比如来自另一个域的域本地组。您可以查看详细信息。下面是切换到使用System.DirectoryServices.AccountManagement时代码的外观。以下代码可以找到此用户分配给的直接组,其中包括主组

UserPrincipal user = UserPrincipal.FindByIdentity(new PrincipalContext (ContextType.Domain, "mydomain.com"), IdentityType.SamAccountName, "username");
foreach (GroupPrincipal group in user.GetGroups())
{
    Console.Out.WriteLine(group);
}

如果您使用用户名和密码建立LDAP连接以连接到Active Directory,以下是我用于正确连接的代码:

using System.DirectoryServices.AccountManagement;

// ...

// Connection information
var connectionString = "LDAP://domain.com/DC=domain,DC=com";
var connectionUsername = "your_ad_username";
var connectionPassword = "your_ad_password";

// Get groups for this user
var username = "myusername";

// Split the LDAP Uri
var uri = new Uri(connectionString);
var host = uri.Host;
var container = uri.Segments.Count() >=1 ? uri.Segments[1] : "";

// Create context to connect to AD
var princContext = new PrincipalContext(ContextType.Domain, host, container, connectionUsername, connectionPassword);

// Get User
UserPrincipal user = UserPrincipal.FindByIdentity(princContext, IdentityType.SamAccountName, username);

// Browse user's groups
foreach (GroupPrincipal group in user.GetGroups())
{
    Console.Out.WriteLine(group.Name);
}

以下是对我有用的代码:

public ArrayList GetBBGroups(WindowsIdentity identity)
{
    ArrayList groups = new ArrayList();

    try
    {
        String userName = identity.Name;
        int pos = userName.IndexOf(@"\");
        if (pos > 0) userName = userName.Substring(pos + 1);

        PrincipalContext domain = new PrincipalContext(ContextType.Domain, "riomc.com");
        UserPrincipal user = UserPrincipal.FindByIdentity(domain, IdentityType.SamAccountName, userName);

        DirectoryEntry de = new DirectoryEntry("LDAP://RIOMC.com");
        DirectorySearcher search = new DirectorySearcher(de);
        search.Filter = "(&(objectClass=group)(member=" + user.DistinguishedName + "))";
        search.PropertiesToLoad.Add("samaccountname");
        search.PropertiesToLoad.Add("cn");

        String name;
        SearchResultCollection results = search.FindAll();
        foreach (SearchResult result in results)
        {
            name = (String)result.Properties["samaccountname"][0];
            if (String.IsNullOrEmpty(name))
            {
                name = (String)result.Properties["cn"][0];
            }
            GetGroupsRecursive(groups, de, name);
        }
    }
    catch
    {
        // return an empty list...
    }

    return groups;
}

public void GetGroupsRecursive(ArrayList groups, DirectoryEntry de, String dn)
{
    DirectorySearcher search = new DirectorySearcher(de);
    search.Filter = "(&(objectClass=group)(|(samaccountname=" + dn + ")(cn=" + dn + ")))";
    search.PropertiesToLoad.Add("memberof");

    String group, name;
    SearchResult result = search.FindOne();
    if (result == null) return;

    group = @"RIOMC\" + dn;
    if (!groups.Contains(group))
    {
        groups.Add(group);
    }
    if (result.Properties["memberof"].Count == 0) return;
    int equalsIndex, commaIndex;
    foreach (String dn1 in result.Properties["memberof"])
    {
        equalsIndex = dn1.IndexOf("=", 1);
        if (equalsIndex > 0)
        {
            commaIndex = dn1.IndexOf(",", equalsIndex + 1);
            name = dn1.Substring(equalsIndex + 1, commaIndex - equalsIndex - 1);
            GetGroupsRecursive(groups, de, name);
        }
    }
}
我对使用
AttributeValuesMultiString
recursive方法的代码进行了200次循环测试,测试了它的性能;它的工作速度快了1.3倍。
这可能是因为我们的广告设置。两个代码段给出了相同的结果。

此代码的运行速度更快(比我以前的版本快了两个1.5版本):

公共列表GetUserGroups(WindowsIdentity) { 列表组=新列表(); 字符串userName=identity.Name; int pos=userName.IndexOf(@“\”); 如果(pos>0)userName=userName.Substring(pos+1); PrincipalContext域=新PrincipalContext(ContextType.domain,“riomc.com”); UserPrincipal user=UserPrincipal.FindByIdentity(域,IdentityType.SamAccountName,用户名);//NGeodakov DirectoryEntry de=newdirectoryEntry(“LDAP://RIOMC.com”); DirectorySearcher search=新的DirectorySearcher(de); search.Filter=“(&(objectClass=group)(member=“+user.differentiedName+”)”; search.PropertiesToLoad.Add(“cn”); search.PropertiesToLoad.Add(“samaccountname”); search.PropertiesToLoad.Add(“memberOf”); SearchResultCollection results=search.FindAll(); foreach(搜索结果中的搜索结果sr) { GetUserGroupsRecursive(组、sr、de); } 返回组; } public void GetUserGroupsRecursive(列表组、搜索结果sr、目录条目de) { if(sr==null)返回; 字符串组=(字符串)sr.Properties[“cn”][0]; if(String.IsNullOrEmpty(组)) { 组=(字符串)sr.Properties[“samaccountname”][0]; } 如果(!groups.Contains(组)) { 组。添加(组); } 目录搜索器搜索; 搜索结果sr1; 字符串名; int equalindex,commaIndex; foreach(sr.Properties[“memberof”]中的字符串dn) { equalsIndex=dn.IndexOf(“=”,1); 如果(相等索引>0) { commaIndex=dn.IndexOf(“,”,等式索引+1); name=dn.Substring(equalsIndex+1,commaIndex-equalsIndex-1); 搜索=新的DirectorySearcher(de); search.Filter=“(&(objectClass=group)(|(cn=“+name+”)(samaccountname=“+name+”))”)”; search.PropertiesToLoad.Add(“cn”); search.PropertiesToLoad.Add(“samaccountname”); search.PropertiesToLoad.Add(“memberOf”); sr
using System.DirectoryServices.AccountManagement;

// ...

// Connection information
var connectionString = "LDAP://domain.com/DC=domain,DC=com";
var connectionUsername = "your_ad_username";
var connectionPassword = "your_ad_password";

// Get groups for this user
var username = "myusername";

// Split the LDAP Uri
var uri = new Uri(connectionString);
var host = uri.Host;
var container = uri.Segments.Count() >=1 ? uri.Segments[1] : "";

// Create context to connect to AD
var princContext = new PrincipalContext(ContextType.Domain, host, container, connectionUsername, connectionPassword);

// Get User
UserPrincipal user = UserPrincipal.FindByIdentity(princContext, IdentityType.SamAccountName, username);

// Browse user's groups
foreach (GroupPrincipal group in user.GetGroups())
{
    Console.Out.WriteLine(group.Name);
}
public ArrayList GetBBGroups(WindowsIdentity identity)
{
    ArrayList groups = new ArrayList();

    try
    {
        String userName = identity.Name;
        int pos = userName.IndexOf(@"\");
        if (pos > 0) userName = userName.Substring(pos + 1);

        PrincipalContext domain = new PrincipalContext(ContextType.Domain, "riomc.com");
        UserPrincipal user = UserPrincipal.FindByIdentity(domain, IdentityType.SamAccountName, userName);

        DirectoryEntry de = new DirectoryEntry("LDAP://RIOMC.com");
        DirectorySearcher search = new DirectorySearcher(de);
        search.Filter = "(&(objectClass=group)(member=" + user.DistinguishedName + "))";
        search.PropertiesToLoad.Add("samaccountname");
        search.PropertiesToLoad.Add("cn");

        String name;
        SearchResultCollection results = search.FindAll();
        foreach (SearchResult result in results)
        {
            name = (String)result.Properties["samaccountname"][0];
            if (String.IsNullOrEmpty(name))
            {
                name = (String)result.Properties["cn"][0];
            }
            GetGroupsRecursive(groups, de, name);
        }
    }
    catch
    {
        // return an empty list...
    }

    return groups;
}

public void GetGroupsRecursive(ArrayList groups, DirectoryEntry de, String dn)
{
    DirectorySearcher search = new DirectorySearcher(de);
    search.Filter = "(&(objectClass=group)(|(samaccountname=" + dn + ")(cn=" + dn + ")))";
    search.PropertiesToLoad.Add("memberof");

    String group, name;
    SearchResult result = search.FindOne();
    if (result == null) return;

    group = @"RIOMC\" + dn;
    if (!groups.Contains(group))
    {
        groups.Add(group);
    }
    if (result.Properties["memberof"].Count == 0) return;
    int equalsIndex, commaIndex;
    foreach (String dn1 in result.Properties["memberof"])
    {
        equalsIndex = dn1.IndexOf("=", 1);
        if (equalsIndex > 0)
        {
            commaIndex = dn1.IndexOf(",", equalsIndex + 1);
            name = dn1.Substring(equalsIndex + 1, commaIndex - equalsIndex - 1);
            GetGroupsRecursive(groups, de, name);
        }
    }
}
    public List<String> GetUserGroups(WindowsIdentity identity)
    {
        List<String> groups = new List<String>();

        String userName = identity.Name;
        int pos = userName.IndexOf(@"\");
        if (pos > 0) userName = userName.Substring(pos + 1);

        PrincipalContext domain = new PrincipalContext(ContextType.Domain, "riomc.com");
        UserPrincipal user = UserPrincipal.FindByIdentity(domain, IdentityType.SamAccountName, userName); // NGeodakov

        DirectoryEntry de = new DirectoryEntry("LDAP://RIOMC.com");
        DirectorySearcher search = new DirectorySearcher(de);
        search.Filter = "(&(objectClass=group)(member=" + user.DistinguishedName + "))";
        search.PropertiesToLoad.Add("cn");
        search.PropertiesToLoad.Add("samaccountname");
        search.PropertiesToLoad.Add("memberOf");

        SearchResultCollection results = search.FindAll();
        foreach (SearchResult sr in results)
        {
            GetUserGroupsRecursive(groups, sr, de);
        }

        return groups;
    }

    public void GetUserGroupsRecursive(List<String> groups, SearchResult sr, DirectoryEntry de)
    {
        if (sr == null) return;

        String group = (String)sr.Properties["cn"][0];
        if (String.IsNullOrEmpty(group))
        {
            group = (String)sr.Properties["samaccountname"][0];
        }
        if (!groups.Contains(group))
        {
            groups.Add(group);
        }

        DirectorySearcher search;
        SearchResult sr1;
        String name;
        int equalsIndex, commaIndex;
        foreach (String dn in sr.Properties["memberof"])
        {
            equalsIndex = dn.IndexOf("=", 1);
            if (equalsIndex > 0)
            {
                commaIndex = dn.IndexOf(",", equalsIndex + 1);
                name = dn.Substring(equalsIndex + 1, commaIndex - equalsIndex - 1);

                search = new DirectorySearcher(de);
                search.Filter = "(&(objectClass=group)(|(cn=" + name + ")(samaccountname=" + name + ")))";
                search.PropertiesToLoad.Add("cn");
                search.PropertiesToLoad.Add("samaccountname");
                search.PropertiesToLoad.Add("memberOf");
                sr1 = search.FindOne();
                GetUserGroupsRecursive(groups, sr1, de);
            }
        }
    }
//Get Direct+Indirect Memberships of User (where SID is XXXXXX)

string str = "(& (objectCategory=group)(member:1.2.840.113556.1.4.1941:=<SID=XXXXXX>) )";

//Get Direct+Indirect **Domain Local** Memberships of User (where SID is XXXXXX)

string str2 = "(& (objectCategory=group)(|(groupType=-2147483644)(groupType=4))(member:1.2.840.113556.1.4.1941:=<SID=XXXXXX>) )";

//TAA DAA
private IEnumerable<string> GetGroupsForDistinguishedName(DirectoryEntry domainDirectoryEntry, string distinguishedName)
{
    var groups = new List<string>();
    if (!string.IsNullOrEmpty(distinguishedName))
    {
        var getGroupsFilterForDn = $"(&(objectCategory=group)(member:1.2.840.113556.1.4.1941:={distinguishedName}))";
        using (DirectorySearcher dirSearch = new DirectorySearcher(domainDirectoryEntry))
        {
            dirSearch.Filter = getGroupsFilterForDn;
            dirSearch.PropertiesToLoad.Add("name");

            using (var results = dirSearch.FindAll())
            {
                foreach (SearchResult result in results)
                {
                    if (result.Properties.Contains("name"))
                        groups.Add((string)result.Properties["name"][0]);
                }
            }
        }
    }

    return groups;
}