Search ActiveDirectory using full name in C#? - c#

UserPrincipal's FindByIdentity method allows me to search ActiveDirectory using username.
However, I also want to be able to search using user's real name (e.g. Wayne, Bruce)
How can I do this?

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
// 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);
// 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.

Related

How to get down-level logon name from UserPrincipal in .Net

I have the following search query where I use a User Principal Name identification:
PrincipalContext principalContext = new PrincipalContext(ContextType.Domain);
var user = UserPrincipal.FindByIdentity(principalContext, IdentityType.UserPrincipalName, "user1#domain1.local"); //the searched UPN will be dynamic!
After I get the UserPrincipal object, I have to create a down-level logon format (domain1\user1).
Unfortunately I have the following distinguished name:
CN=User One,OU=Every employee,DC=domain1,DC=local
It looks like user.Context.Name is null which is claimed to be the name of the domain.
Also, if the selected user is a local one, I should get the machine1\localuser1 value.
The SamAccountName contains only the user name, without the context (user1).
What is the best way to get that format from any UserPrincipal object?
If you need to do this for machine accounts, then your answer is the way to go.
But another way, strictly for Active Directory (in case it comes in handy some other time), is to look at the msDS-PrincipalName attribute, which you can get via the underlying DirectoryEntry object:
var de = (DirectoryEntry) user.GetUnderlyingObject();
de.RefreshCache(new [] { "msDS-PrincipalName" }); //retrieve it from AD
var domainUsername = de.Properties["msDS-PrincipalName"].Value;
Since it's a constructed attribute, it's not returned unless you specifically ask for it, which is what you use RefreshCache for.
The down-level logon format can be obtained via an NTAccount object. However, it requires some translation to convert the Principal's SID to an NTAccount:
string downLevelLogonName =
userPrincipal.Sid.Translate(typeof(System.Security.Principal.NTAccount)).ToString();
Using that code works in both case (domain or local computer users).

ASPX C# Search for a User in Active Directory

Does anyone know the best way to search for a single user within Active Directory using DirectoryServices? I have code that currently lists all sub 'OU's' under a given LDAP path but I now want to add the feature of searching for a user under the path too. Could the code just be adapted to search for users?
I have included my code that lists all users in the current OU:
DirectoryEntry Ldap = new DirectoryEntry("LDAP://" + ouselect.SelectedValue + ";" + LDAPRoot, LDAPUser, LDAPPass);
DirectorySearcher ad_search = new DirectorySearcher(Ldap);
ad_search.Filter = "(objectClass=User)";
ad_search.SearchScope = SearchScope.Subtree;
ad_search.PropertiesToLoad.Add("samaccountname");
Any pointer that anyone can offer would be excellent.
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 a user
UserPrincipal user = UserPrincipal.FindByIdentity(ctx, "SomeUserName");
if(user != null)
{
// do something here....
}
}
The new S.DS.AM makes it really easy to play around with users and groups in AD!
PS: the PrincipalContext has a number of different overloads for its constructor - you can also define a username/password to use to query Active Directory, and you can also define a "starting" container, if you need to. Check out the MSDN documentation for details on this.
Your code is almost there. Just change your filter to search for a particular AD Attribute, rather than all users.
ad_search.Filter = string.Format("(department={0})", department);
ad_search.Filter = string.Format("(displayName={0})", "James Doe");
ad_search.Filter = string.Format("(sAMAccountName={0})", "some.username");

PrincipalContext for query in Active Directory

I want to make a few simple reports from Active Directory. Following discussions, etc. I found that if I use .NET FW 3.5 and up, it is appropriate to use PrincipalContext. I would like to understand principles and what I can do with this new feature (unlike DirectoryEntry).
Code skeleton
// 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
// which has a password that will expire in 3 days or less
UserPrincipal userTemplate = new UserPrincipal(ctx);
userTemplate.AdvancedSearchFilter.AccountExpirationDate(DateTime.Today.AddDays(3), MatchType.LessThanOrEquals);
// instantiate searcher
PrincipalSearcher searcher = new PrincipalSearcher(userTemplate);
// enumerate matching users
foreach (Principal foundPrincipal in searcher.FindAll())
{
UserPrincipal foundUser = (foundPrincipal as UserPrincipal);
if (foundUser != null)
{
// do something with users found - e.g. send e-mail
}
}
It is possible by code up add this properties for login to LDAP?:
what LDAP is used (version 2 or 3)
how set port on which LDAP is running
how to work if I need SSL connection? (different port, must be special requirements)
Furthermore, can I do with AdvancedSearchFilter this conditions?
(I found only AccountExpirationDate and AccountLockoutDate)
users password will expire in the near future
users password has expired
check if the user's password can expire
users account expires (account, no password)
expired users account (account, no password)
user account not expired
sorry for the late reply. The solution I found these two links, which describes all the information. Just as it only needs to combine with the code above.
retrieve the value of "Minimum Password Length" in domain password policy
House of Derek - Password expiration email utility

Could not query AD without distinguished name in SearchRequest?

I am running a test Active directory and am trying to query with ldap. I created a searchrequest object with distingueshed name empty and a filter this is throwing noSuchObject error code with "object does not exist" message. I am only getting this from my test AD , if I use my company's production AD I am not getting exception, just a response with no hit. What do I need to change in my test AD to see similar behaviour ?
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
// and with specified last name (surname)
UserPrincipal qbeUser = new UserPrincipal(ctx);
qbeUser.Surname = "Willis";
// 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
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.
#marc_s answered by giving you a way of searching
Back to your question, just a recall :
A LDAP search is
The nod from which you ask to begin the search (in your case the DN of your OU)
The scope of your search (base, onelevel, subtree)
The filter of your search ((objectClass=group))
The attributes you want to retreive
In you case it works when your ADSI layer is able to find a default Domain. So I think that you have to create a real LDAP-SEARCH request en perhaps also give credentials.
Thanks for the other answers. I solved my problem by using GC port 3268 instead of DC port 389 in the connection.

Querying LDAP for Usergroup of Specific User

I have to check usergroups of LDAP Active Directory for a specific user in C#. Mean I pass this username to a method and it returns me list of group from that user belongs. Can You Please help me in this. Im Searching alot But Everytime get new error.
LDAP Path: 192.168.1.4
Domain Name: Arslan
UserName: ArslanP
Password: testad
Since 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
Basically, add a reference to the assembly System.DirectoryServices.AccountManagement, and then you can define a domain context and easily find users and/or groups in AD:
using System.DirectoryServices.AccountManagement;
public List<GroupPrincipal> GetGroupsForUser(string username)
{
List<GroupPrincipal> result = new List<GroupPrincipal>();
// set up domain context - if you do a lot of requests, you might
// want to create that outside the method and pass it in as a parameter
PrincipalContext ctx = new PrincipalContext(ContextType.Domain);
// find user by name
UserPrincipal user = UserPrincipal.FindByIdentity(username);
// get the user's groups
if(user != null)
{
foreach(GroupPrincipal gp in user.GetAuthorizationGroups())
{
result.Add(gp);
}
}
return result;
}
The new S.DS.AM makes it really easy to play around with users and groups in AD:
This related question may help you:
Get List of Users From Active Directory In A Given AD Group
It asks the reverse question, which is how to qet a list of users when you know the group, but other answers may be of use to you as well.
See also the answer to this question:
How to get all the AD groups for a particular user?

Categories

Resources