Get all the parent AD groups a user belongs to - c#

I want to get all the Active Directory groups in which a particular user is a member.
I do have the script to get all the immediate AD groups for a user (see codes below).
However, how do I get all the parent groups for each of the immediate AD groups the user belongs to?
e.g. I am directly part of the AD group called IT Team Managers. This group is member of a parent group called IT Team National etc. How do I get this parent group from my code?
Thanks so much in advance!
DirectorySearcher ouSearch = new DirectorySearcher(entry);
ouSearch.Filter = "(&(objectClass=User)(sAMAccountName=" + username + "))";
//ouSearch.PropertiesToLoad.Add("samAccountName");
ouSearch.PropertiesToLoad.Add("memberOf");
ouSearch.SearchScope = SearchScope.Subtree;
SearchResult allOUS = ouSearch.FindOne();
//foreach (string g in allOUS.Properties["memberOf"])
{
equalsIndex = g.IndexOf("=", 1);
commaIndex = g.IndexOf(",", 1);
if (equalsIndex == -1)
{
return null;
}
groupNames.Append(g.Substring((equalsIndex + 1), (commaIndex - equalsIndex) - 1));
groupNames.Append(",");
}

If you're on .NET 3.5 and up, you should check out the System.DirectoryServices.AccountManagement (S.DS.AM) namespace. Read all about it here:
Managing Directory Security Principals in the .NET Framework 3.5
MSDN docs on System.DirectoryServices.AccountManagement
Basically, you can define a domain context and easily find users and/or groups in AD:
// set up domain context
PrincipalContext ctx = new PrincipalContext(ContextType.Domain);
// find a user
UserPrincipal user = UserPrincipal.FindByIdentity(ctx, "SomeUserName");
if(user != null)
{
// get the "authorization groups" the user is a member of - recursively
var authGroups = user.GetAuthorizationGroups();
// iterate over groups
foreach(Principal p in authGroups)
{
// do something with groups ....
}
}
The new S.DS.AM makes it really easy to play around with users and groups in AD!

Related

Get user names of Active Directory group in c#

I need to get user details of a particular Active Directory group. I am using this code:
var result = grpResponse.Entries[0];
if (result.Attributes["member"] != null)
{
for (var i = 0; i < result.Attributes["member"].Count; i++)
{
var filter = result.Attributes["member"][i].ToString();
var query = "(&(objectClass=user)(" + filter + "))"; // Here I need username to use like cn=username
var userRequest = new SearchRequest(distinguishedName, query,
SearchScope.Subtree);
In filter I am getting something like
CN=Name,OU=something,DC=example
How can I take this cn value i.e user name alone?
If you're on .NET 3.5 and up, you should check out the System.DirectoryServices.AccountManagement (S.DS.AM) namespace.
Basically, you can define a domain context and easily find users and/or groups in AD:
// set up domain context - limit to the OU you're interested in
using (PrincipalContext ctx = new PrincipalContext(ContextType.Domain, null, "OU=YourOU,DC=YourCompany,DC=Com"))
{
// find the group in question
GroupPrincipal group = GroupPrincipal.FindByIdentity(ctx, "YourGroupNameHere");
// if found....
if (group != null)
{
// iterate over the group's members
foreach (Principal p in group.GetMembers())
{
Console.WriteLine("{0}: {1}", p.StructuralObjectClass, p.DisplayName);
// do whatever else you need to do to those members
}
}
}
The new S.DS.AM makes it really easy to play around with users and groups in AD!
Read more about it here:
MSDN docs on System.DirectoryServices.AccountManagement
The below is exactly what I needed.
The OuString you use like ours may have has multiple parts - both OU & DC
bstring OUString = "OU=Groups,OU=Accounts,DC=nw,DC=nos,DC=ourcompanyName,DC=com" ;
using (PrincipalContext ctx = new PrincipalContext(ContextType.Domain, null, OUString))

How to know if user exists in AD Group efficiently

In a sharepoint solution I need to get all users from an AD Group, for the time being this AD group can have 30 users, but in the future, we could replace the AD group with one that has 1000 users. and because this code is executed for each user on each request (its a navigation component to show/hide the OneDrive Link), then I need it to be as efficient as possible.
// Get all users from a group recursively.
var context = new System.DirectoryServices.AccountManagement.PrincipalContext(ContextType.Domain);
GroupPrincipal group = new GroupPrincipal(context ,farm.Properties[GlobalNavigationConstants.Keys.GlobalNavigationOneDriveADGroup].ToString());
PrincipalSearchResult<Principal> members = group.GetMembers(true);
var list = members.OfType<UserPrincipal>().ToList();
//Get current user
var loginName = SPContext.Current.Web.CurrentUser.LoginName;
//How to check if loginname is on list efficiently?
How can I do this as fast as possible?
Warning, NOT tested.
var context = new System.DirectoryServices.AccountManagement.PrincipalContext(ContextType.Domain);
GroupPrincipal group = new GroupPrincipal(context,
farm.Properties[GlobalNavigationConstants.Keys.GlobalNavigationOneDriveADGroup].ToString());
UserPrincipal usr = UserPrincipal.FindByIdentity(context,
IdentityType.Sid,
SPContext.Current.Web.CurrentUser.Sid);
var found = usr.IsMemberOf(group);

Search for subdirectory in a given directory in LDAP

I would like to find the subdirectories for a given directory. so far my code looks like this..
It does connect, but now I am not sure how to get the groups under the MainGroup
DirectoryEntry _de = new DirectoryEntry("LDAP://xxx.com/DC=xxx,DC=org");
DirectorySearcher ds = new DirectorySearcher(_de);
ds.Filter = "(&(objectClass=group)(CN=MainGroup)";
ds.SearchScope = SearchScope.Subtree;
ds.PageSize = 1000;
ds.SizeLimit = 0;
foreach (SearchResult result in ds.FindAll())
{
}
Thanks for your time!
If you're on .NET 3.5 and up, you should check out the System.DirectoryServices.AccountManagement (S.DS.AM) namespace. Read all about it here:
Managing Directory Security Principals in the .NET Framework 3.5
MSDN docs on System.DirectoryServices.AccountManagement
Basically, you can define a domain context and easily find users and/or groups in AD:
// set up domain context
using (PrincipalContext ctx = new PrincipalContext(ContextType.Domain))
{
// find the group in question
GroupPrincipal group = GroupPrincipal.FindByIdentity(ctx, "MainGroup");
// if found....
if (group != null)
{
// iterate over members
foreach (Principal p in group.GetMembers())
{
Console.WriteLine("{0}: {1}", p.StructuralObjectClass, p.DisplayName);
// do whatever you need to do to those members
// if you need to find the groups that are members of 'MainGroup'
GroupPrincipal group = p as GroupPrincipal;
if(group != null)
{
// now you have a group that is member of 'MainGroup' - do what you need here
}
}
}
}
The new S.DS.AM makes it really easy to play around with users and groups in AD!

How to get SID of a group once i get groups of a user in Active Directory?

I am using DirectorySearcher to get groups of a User in ActiveDirectory.
My Question is how to get SID associated with each group once i get user groups using "memberOf"?
I am working in .NETFramework 2.0 Environment.
DirectoryEntry entry = new DirectoryEntry(string.Format("LDAP://{0}", sUserDomain));
DirectorySearcher mySearcher = new DirectorySearcher(entry);
mySearcher.Filter = string.Format("(&(objectClass=user) (cn= {0}))", ui.DisplayName.ToString());
mySearcher.PropertiesToLoad.Add("memberOf");
SearchResult searchresult = mySearcher.FindOne();
There is no way to do it in one single LDAP search because memberOf returns a distinguish name. You have to do another bind to get the objectSid attribute from the group object. Here is the code.
DirectoryEntry entry = new DirectoryEntry(string.Format("LDAP://{0}", sUserDomain));
DirectorySearcher mySearcher = new DirectorySearcher(entry);
mySearcher.Filter = string.Format("(&(objectClass=user) (cn= {0}))", ui.DisplayName.ToString());
mySearcher.PropertiesToLoad.Add("memberOf");
SearchResult searchresult = mySearcher.FindOne();
foreach (string dn in searchresult.Properties["memberOf"])
{
DirectoryEntry group = new DirectoryEntry(string.Format("LDAP://{0}/{1}", sUserDomain, dn));
SecurityIdentifier sid = new SecurityIdentifier(group.Properties["objectSid"][0] as byte[], 0);
Console.Out.WriteLine(sid.Value);
}
If you're on .NET 3.5 and up, you should check out the System.DirectoryServices.AccountManagement (S.DS.AM) namespace. Read all about it here:
Managing Directory Security Principals in the .NET Framework 3.5
MSDN docs on System.DirectoryServices.AccountManagement
Basically, you can define a domain context and easily find users and/or groups in AD:
// define context for current domain
using(PrincipalContext ctx = new PrincipalContext(ContextType.Domain))
{
// find user
UserPrincipal user = UserPrincipal.FindByIdentity(ctx, "YourNameHere");
if (user != null)
{
// get groups the user is a member of
var groups = current.GetGroups();
// iterate over all those groups
foreach(var group in groups)
{
// fetch the SID for each group
var sid = group.Sid;
}
}
}
The new S.DS.AM makes it really easy to play around with users and groups in AD!
Have a look at his article:
Retrieving user SID using DirectoryEntry and DirectorySearcher
This gives you a full working example for retrieving the SID.

Querying AD for finding all groups of a user - Missing one group

I've the following code to query AD using DirectorySearcher to get all the AD groups for a user.
List<string> Groups = new List<string>();
//initialize the directory entry object
DirectoryEntry dirEntry = new DirectoryEntry(ldapPath);
//directory searcher
DirectorySearcher dirSearcher = new DirectorySearcher(dirEntry);
//enter the filter
dirSearcher.Filter = string.Format("(&(objectClass=user)(sAMAccountName={0}))", username);
//get the member of properties for the search result
dirSearcher.PropertiesToLoad.Add("memberOf");
int propCount;
SearchResult dirSearchResults = dirSearcher.FindOne();
propCount = dirSearchResults.Properties["memberOf"].Count;
string dn;
int equalsIndex;
int commaIndex;
for (int i = 0; i <= propCount - 1; i++)
{
dn = dirSearchResults.Properties["memberOf"][i].ToString();
equalsIndex = dn.IndexOf("=", 1);
commaIndex = dn.IndexOf(",", 1);
if (equalsIndex == -1)
{
return null;
}
if (!Groups.Contains(dn.Substring((equalsIndex + 1), (commaIndex - equalsIndex) - 1)))
{
Groups.Add(dn.Substring((equalsIndex + 1), (commaIndex - equalsIndex) - 1));
}
}
return Groups;
But when i check the 'memberof' tab in AD for a user I've one additional group 'Domain Users' which I'm not getting through this code.
Any ideas? Why I'm not getting 'Domain Users' in the 'memberof' collection?
Groups can be members of other groups. Maybe your users are not direct members, but only indirect members?
I do iterate all groups for child groups, too, when retrieving the groups on an AD.
Be warned that you may get endless recursion, since groups can (indirectly) contain each other. I had a hard time finding this out :-( Now I remember each processed group in a "global" list to only process it once to avoid this).
I've written a CodeProject article with some general purpose libraries, that contains AD classes, too. (See the classes in the "/Tools/DirectoryServices/" sub folder in the downloaded ZIP file).
This is old, but for anyone else searching, the reason that the memberof attribute was missing "Domain Users" is because that was the AD object's PRIMARY GROUP. To find a user's primary group, you need to:
Get the user's primaryGroupID attribute, which is the unique serial ID of the group object within the domain
Construct the group's objectSID (take the user object's objectSID and replace the last digit group with the primaryGroupID)
Get the group based on the constructed SID

Categories

Resources