I have this code:
public static DataTable ExecutesAMAccountNameQuery(string sAMAccountName)
{
string filter = "(&(objectCategory=person)(objectClass=user)(sAMAccountName=" + sAMAccountName + "))";
return ExecuteADQuery("GC:", filter);
}
It only works with the full username, I dont know the syntax to make it work with wildcards, like a LIKE in sql?
Thanks
If you're using .NET 3.5 or newer, you can use a PrincipalSearcher and a "query-by-example" principal to do your searching:
// create your domain context
PrincipalContext ctx = new PrincipalContext(ContextType.Domain);
// define a "query-by-example" principal - here, we search for a UserPrincipal
UserPrincipal qbeUser = new UserPrincipal(ctx);
qbeUser.SamAccountName = "Esteban*";
// create your principal searcher passing in the QBE principal
PrincipalSearcher srch = new PrincipalSearcher(qbeUser);
// find all matches
foreach(var found in srch.FindAll())
{
// do whatever here - "found" is of type "Principal" - it could be user, group, computer.....
}
If you haven't already - absolutely read the MSDN article Managing Directory Security Principals in the .NET Framework 3.5 which shows nicely how to make the best use of the new features in System.DirectoryServices.AccountManagement. Or see the MSDN documentation on the System.DirectoryServices.AccountManagement namespace.
Of course, depending on your need, you might want to specify other properties on that "query-by-example" user principal you create:
DisplayName (typically: first name + space + last name)
SAM Account Name - your Windows/AD account name
User Principal Name - your "username#yourcompany.com" style name
You can specify any of the properties on the UserPrincipal and use those as "query-by-example" for your PrincipalSearcher.
Related
I have this code:
public static DataTable ExecutesAMAccountNameQuery(string sAMAccountName)
{
string filter = "(&(objectCategory=person)(objectClass=user)(sAMAccountName=" + sAMAccountName + "))";
return ExecuteADQuery("GC:", filter);
}
It only works with the full username, I dont know the syntax to make it work with wildcards, like a LIKE in sql?
Thanks
If you're using .NET 3.5 or newer, you can use a PrincipalSearcher and a "query-by-example" principal to do your searching:
// create your domain context
PrincipalContext ctx = new PrincipalContext(ContextType.Domain);
// define a "query-by-example" principal - here, we search for a UserPrincipal
UserPrincipal qbeUser = new UserPrincipal(ctx);
qbeUser.SamAccountName = "Esteban*";
// create your principal searcher passing in the QBE principal
PrincipalSearcher srch = new PrincipalSearcher(qbeUser);
// find all matches
foreach(var found in srch.FindAll())
{
// do whatever here - "found" is of type "Principal" - it could be user, group, computer.....
}
If you haven't already - absolutely read the MSDN article Managing Directory Security Principals in the .NET Framework 3.5 which shows nicely how to make the best use of the new features in System.DirectoryServices.AccountManagement. Or see the MSDN documentation on the System.DirectoryServices.AccountManagement namespace.
Of course, depending on your need, you might want to specify other properties on that "query-by-example" user principal you create:
DisplayName (typically: first name + space + last name)
SAM Account Name - your Windows/AD account name
User Principal Name - your "username#yourcompany.com" style name
You can specify any of the properties on the UserPrincipal and use those as "query-by-example" for your PrincipalSearcher.
I have implemented System.DirectoryServices.AccountManagement for authentication into my webapps finding users (UserPrincipal) byidentity given username. However, I have several cases where I need to get AD accounts given only an employeeID. Is there a good way to get a UserPrincipal (or even just the sAMAccountName) given an employeeID in AccountManagement?
I currently have this working to grab users by username:
PrincipalContext adAuth = new PrincipalContext(ContextType.Domain, Environment.UserDomainName);
//get user
UserPrincipal usr = UserPrincipal.FindByIdentity(adAuth, username);
I have been searching and can't seem to find answers to confirm whether this can or cannot be done. If I can't do it with AccountManagement, what's the best way to get sAMAccountName given employeeID?
You don't need to go outside of the System.DirectoryServices.AccountManagement namespace.
UserPrincipal searchTemplate = new UserPrincipal(adAuth);
searchTemplate.EmployeeID = "employeeID";
PrincipalSearcher ps = new PrincipalSearcher(searchTemplate);
UserPrincipal user = (UserPrincipal)ps.FindOne();
In this example, if no user is found the user object will be null. If you want to find a collection of UserPrinicipal object you can use the FindAll method on the PrincipalSearcher (ps) object.
Also note that the FindOne method returns a Principal object, but we know it is really a UserPrincipal and should be handled (casted) as such since UserPrincipal is part of the search filter.
So, I found a way using System.DirectoryServices as below, but it seems rather lengthy:
string username = "";
DirectoryEntry entry = new DirectoryEntry(_path);
//search for a DirectoryEntry based on employeeID
DirectorySearcher search = new DirectorySearcher(entry);
search.Filter = "(employeeID=" + empID + ")";
//username
search.PropertiesToLoad.Add("sAMAccountName");
SearchResult result = search.FindOne();
//get sAMAccountName property
username = result.Properties["sAMAccountName"][0].ToString();
Of course, I could use this for the other attributes, but I really like the strongly-typed attributes with AccountManagement.
I trying to search my organization Active directory for users.
If the FirstName or LastName or DisplayName matches a particular string value, it should return the users.
My Code:
// create your domain context
PrincipalContext ctx = new PrincipalContext(ContextType.Domain);
UserPrincipal qbeUser = new UserPrincipal(ctx);
qbeUser.GivenName = "Ramesh*";
// qbeUser.Surname = "Ramesh*";
// qbeUser.DisplayName= "Ramesh*";
PrincipalSearcher srch = new PrincipalSearcher(qbeUser);
// find all matches
foreach(var found in srch.FindAll())
{
//
}
The problem is that I am able to search by only one filter.
I am able to AND the filters but not OR. Whether any solutions are available?
See a possible solution for this issue in this other SO question.
You will need to use the extensibility of UserPrincipal to create a descendant class, in order to get access to the anr property (anr = ambiguous name resolution) which allows searches in multiple name-related properties at once.
Have a look at the DirectorySearcher.
This article may help.
I'm looking at the DirectoryServices namespace and I'm trying to get a list of all groups in the AD and load them into a listbox.
When I select a group, I want it to fill a text box with the manager's name as well another listbox with all users assigned to that group. I'm having a hard time wrapping my head around the process. Could someone help me out?
If I get a full example of this, I'm fairly sure that I'll understand the bigger picture a lot better. TIA
If you're running on .NET 3.5 or newer, you can use a PrincipalSearcher and a "query-by-example" principal to do your searching:
// create your domain context
PrincipalContext ctx = new PrincipalContext(ContextType.Domain);
// define a "query-by-example" principal - here, we search for a GroupPrincipal
GroupPrincipal qbeGroup = new GroupPrincipal(ctx);
// create your principal searcher passing in the QBE principal
PrincipalSearcher srch = new PrincipalSearcher(qbeGroup);
// find all matches
foreach(var found in srch.FindAll())
{
GroupPrincipal foundGroup = found as GroupPrincipal;
if(foundGroup != null)
{
// do whatever you need to do, e.g. put name into a list of strings or something
}
}
If you haven't already - absolutely read the MSDN article Managing Directory Security Principals in the .NET Framework 3.5 which shows nicely how to make the best use of the new features in System.DirectoryServices.AccountManagement
When you have a given group, you can easily get all its group members by using:
// find the group in question (or load it from e.g. your list)
GroupPrincipal group = GroupPrincipal.FindByIdentity(ctx, "YourGroupNameHere");
// 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
}
}
I came up with something similar to marc_s using the System.DirectoryServices.AccountManagement namespace:
PrincipalContext context = new PrincipalContext(ContextType.Domain);
GroupPrincipal queryPrincipal = new GroupPrincipal(context);
using (PrincipalSearcher searcher = new PrincipalSearcher(queryPrincipal))
using (PrincipalSearchResult<Principal> allPrincipals = searcher.FindAll())
foreach (GroupPrincipal groupPrincipal in allPrincipals.OfType<GroupPrincipal>())
{
// Process group...
foreach (UserPrincipal userPrincipal in groupPrincipal.Members.OfType<UserPrincipal>())
{
// Process group member...
}
}
The UserPrincipal class doesn't appear to expose any members that would allow you to determine if a user is and/or has a manager, but you can still do it by obtaining the DirectoryEntry for the user:
DirectoryEntry userEntry = userPrincipal.GetUnderlyingObject() as DirectoryEntry;
if (userEntry != null)
{
bool isManager = userEntry.Properties["directReports"].Count > 0;
bool isManaged = userEntry.Properties["manager"].Count > 0;
// Perform further processing...
}
You'll need some additional logic, though, to determine if the user is a manager in the group you're currently looking at, rather than some other group. Maybe check the directReports property to see if any of the users contained within are members of the current group.
I use this code:
DirectoryEntry objEntry;
DirectorySearcher objSearchEntry;
SearchResultCollection objSearchResult;
string strFilter = "(&(objectCategory=User))";
objEntry = new DirectoryEntry(conOUPath, conUser, conPwd, AuthenticationTypes.Secure);
objEntry.RefreshCache();
objSearchEntry = new DirectorySearcher(objEntry);
objSearchEntry.Filter=strFilter;
objSearchEntry.SearchScope=SearchScope.Subtree;
objSearchEntry.CacheResults=false;
objSearchResult=objSearchEntry.FindAll();
Each time, it only return 1000 users, but there are 3000 users in that OU.
How can i find all of them ?
If you're on .NET 3.5 or newer, you should check out the PrincipalSearcher and a "query-by-example" principal to do your searching:
// create your domain context
PrincipalContext ctx = new PrincipalContext(ContextType.Domain, "YOURDOMAIN", "OU=SomeOU,DC=YourCompany,DC=com");
// define a "query-by-example" principal - here, we search for a UserPrincipal
// and with the first name (GivenName) of "Bruce"
UserPrincipal qbeUser = new UserPrincipal(ctx);
qbeUser.GivenName = "Bruce";
// create your principal searcher passing in the QBE principal
PrincipalSearcher srch = new PrincipalSearcher(qbeUser);
// set the PageSize on the underlying DirectorySearcher to get all 3000 entries
((DirectorySearcher)srch.GetUnderlyingSearcher()).PageSize = 500;
// find all matches
foreach(var found in srch.FindAll())
{
// do whatever here - "found" is of type "Principal" - it could be user, group, computer.....
}
If you haven't already - absolutely read the MSDN article Managing Directory Security Principals in the .NET Framework 3.5 which shows nicely how to make the best use of the new features in System.DirectoryServices.AccountManagement
Update:
Of course, depending on your need, you might want to specify other properties on that "query-by-example" user principal you create:
Surname (or last name)
DisplayName (typically: first name + space + last name)
SAM Account Name - your Windows/AD account name
User Principal Name - your "username#yourcompany.com" style name
You can specify any of the properties on the UserPrincipal and use those as "query-by-example" for your PrincipalSearcher.
Update #2: If you want to search just inside a given OU, you can define that OU in the constructor of the PrincipalContext.
You need to set the DirectorySearcher.PageSize property to be able to return all the results. For example:
objSearchEntry.PageSize = 500;
Otherwise the number of items returned will be limited by the limit on the server side, which is 1000 by default. There is also something called SizeLimit, which you can set if you want to explicitly limit the number of returned items. If both SizeLimit and PageSize are 0 (default values) then it will use the server side default SizeLimit. A bit counter-intuitive in my opinion.
If you want to return all the results, the only way is to set PageSize to a non-zero value and SizeLimit to 0.