Like search in ActiveDirectory - c#

I am searching LDAP using the following code in C# to poll active directory for users:
DirectoryEntry entry = new DirectoryEntry(ldapPath, userName, password);
DirectorySearcher Searcher = new DirectorySearcher(entry);
Searcher.CacheResults = true;
Searcher.SearchScope = SearchScope.Subtree;
Searcher.Filter = "(&(&(objectCategory=person)(objectClass=user))
(|(samaccountname=" + userSearch.SamAccountName + "*)
(&(GivenName=" + userSearch.FirstName + "*)(SN=" + userSearch.Surname +
"*))))";
Searcher.PropertiesToLoad.AddRange(new string[] {"DisplayName", "GivenName",
"DistinguishedName","Title","manager",
"mail", "physicalDeliveryOfficeName", "DirectReports", "Company",
"Description", "SAMAccountName"});
SearchResultCollection results = Searcher.FindAll();
List<ActiveUser> activeUsers = new List<ActiveUser>();
I ran it with the input parameters userSearch.FirstName = "jo" and userSearch.LastName = "bl" and was expecting one user "Joe Bloggs", but this didn't appear in the result list. If I try this using the name textbox in Active Directory Users and Computers tool in Windows, Joe Bloggs appears as the only user in the list. I am using the correct LDAP path. Am I using the wrong filter to replicate the functionality in the windows tool? Is there a 'like' search on display name?
Any help would be appreciated.

If you're on .NET 3.5 or up, 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 = "Jo*";
qbeUser.Surname = "Bl*";
// 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

Related

Active Directory users import in MVC

I am trying to fetch all the users of particular group from Active Directory of LDAP server. Authentication becomes success but i am getting null in result.
Following is my code.
Domain-172.11.12.123
Email-sample#email.com
password-123456
using (var context = new DirectoryEntry(user.Domain, user.Email, user.Password, AuthenticationTypes.Secure))
{
try
{
string FirstName;
string LastName;
string ADUserName;
string Email;
using (var searcher = new DirectorySearcher(context))
{
searcher.Filter = "(&((&(objectCategory=Person)(objectClass=User)))(samaccountname='user3'))";
List<string> Adusers = new List<string>();
System.DirectoryServices.SearchResult result = searcher.FindOne();
}
}
catch (Exception ex)
{
TempData["message"] = "error";
return RedirectToAction("Index", "ADuserList");
}
}
What wrong is going on.
Thanks in advance
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 for the currently connected AD domain
using (PrincipalContext ctx = new PrincipalContext(ContextType.Domain))
{
// find the group in question
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
}
}
}
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
Update: in order to get all the users of a given OU, the approach is quite different.
You need to create a separate PrincipalContext that defines what OU you're interested in - then you need to use a PrincipalSearcher to get all the users from that OU:
// create your domain context and define what OU to use:
using (PrincipalContext ctx = new PrincipalContext(ContextType.Domain, null, "OU=YourOU,OU=SubOU,dc=YourCompany,dc=com"))
{
// define a "query-by-example" principal - here, we search for any UserPrincipal
UserPrincipal qbeUser = new UserPrincipal(ctx);
// 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.....
}
}

How to create an arraylist of all email addresses in an Active Directory OU in an asp.net c# web forms application?

I have read several posts, but I haven't been able to get anything to work for me. I would like to create an arraylist of all display names within the "Standard Users" OU. I will then use that arraylist to populate a dropdown list. I found the following in another thread, but it provides groups and not users within the specified OU:
public ArrayList Groups()
{
ArrayList groups = new ArrayList();
foreach (System.Security.Principal.IdentityReference group in
System.Web.HttpContext.Current.Request.LogonUserIdentity.Groups)
{
groups.Add(group.Translate(typeof
(System.Security.Principal.NTAccount)).ToString());
}
return groups;
}
Can this be modified to provide the list of users in the Standard Users OU? Or should I use a different approach?
I also found this, but I get an error (red lines under 'std_users') stating 'not all code paths return a value'.
public ArrayList std_users()
{
// List of strings for your names
List<string> allUsers = new List<string>();
// create your domain context and define the OU container to search in
PrincipalContext ctx = new PrincipalContext(ContextType.Domain, "myco.org", "OU=Standard Users, dc=myco, dc=org");
// define a "query-by-example" principal - here, we search for a UserPrincipal (user)
UserPrincipal qbeUser = new UserPrincipal(ctx);
// 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.....
allUsers.Add(found.DisplayName);
}
}
Any help would be greatly appreciated.
I am using c#, Visual Studio 2013 and the framework is 4.5.1.
First off: STOP USING ArrayList - that type is dead since .NET 2.0 and should not be used - use List<string> (or more generally: List<T>) instead - much better for performance and usability!
You can use a PrincipalSearcher and a "query-by-example" principal to do your searching:
public List<string> GetAllEmailsFromUsersContainer()
{
List<string> users = new List<string>();
// create your domain context and bind to the standard CN=Users
// container to get all "standard" users
using (PrincipalContext ctx = new PrincipalContext(ContextType.Domain, null, "CN=Users,dc=YourCompany,dc=com"))
{
// define a "query-by-example" principal - here, we search for a UserPrincipal
// which is not locked out, and has an e-mail address
UserPrincipal qbeUser = new UserPrincipal(ctx);
qbeUser.IsAccountLockedOut = false;
qbeUser.EmailAddress = "*";
// create your principal searcher passing in the QBE principal
PrincipalSearcher srch = new PrincipalSearcher(qbeUser);
// find all matches
foreach(var found in srch.FindAll())
{
users.Add(found.EmailAddress);
}
}
return users;
}
Add return allUsers; to std_users() and let us know if that works for you.

C# search for user in AD

I'm not a programmer by nature so I apologize in advance. I've searched far and wide and have found bits and pieces of 10 different ways to do one thing. What I'm trying to do seems very simple but I'm missing it...I need to search Active Directory using a first name and last name and display all users who match in a listbox. Can someone point me in the right direction, or if someone has already asked the same question link me to it? Thanks in advance!
Try something like this:-
DirectorySearcher d = new DirectorySearcher(somevalue);
d.Filter = string.Format("(&(objectCategory=person)(objectClass=user)(givenname={0})(sn={1}))", firstname, lastname);
Also from How to search for users in Active Directory with C#
//Create a shortcut to the appropriate Windows domain
PrincipalContext domainContext = new PrincipalContext(ContextType.Domain,
"myDomain");
//Create a "user object" in the context
using(UserPrincipal user = new UserPrincipal(domainContext))
{
//Specify the search parameters
user.Name = "he*";
//Create the searcher
//pass (our) user object
using(PrincipalSearcher pS = new PrincipalSearcher())
{
pS.QueryFilter = user;
//Perform the search
using(PrincipalSearchResult<Principal> results = pS.FindAll())
{
//If necessary, request more details
Principal pc = results.ToList()[0];
DirectoryEntry de = (DirectoryEntry)pc.GetUnderlyingObject();
}
}
}
//Output first result of the test
MessageBox.Show(de.Properties["mail"].Value.ToString());
Of course shortly after posting I found my answer :)
// create your domain context
PrincipalContext ctx = new PrincipalContext(ContextType.Domain, "servername","username","password");
UserPrincipal qbeUser = new UserPrincipal(ctx);
qbeUser.GivenName = "fname";
qbeUser.Surname = "lname";
// qbeUser.DisplayName= "fname lname";
PrincipalSearcher srch = new PrincipalSearcher(qbeUser);
// find all matches
foreach (var found in srch.FindAll())
{
lstUser.Items.Add(found.ToString());
}
here is the link: Search Users in Active Directory based on First Name, Last Name and Display Name

How to get username and SID for user by a domain name in ldap

I am trying to get the user information for a specific domain which will be the input of the program. On the basis of the domain name it should return the list of the users name/ or NT Id and SID of the user. I am new for the ldap programming can any one help me for get this list.
If you're on .NET 3.5 and up and talking about Active Directory, then 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)
{
// do something here....
var usersSid = user.Sid;
// not sure what you mean by "username" - the "DisplayName" ? The "SAMAccountName"??
var username = user.DisplayName;
var userSamAccountName = user.SamAccountName;
}
The new S.DS.AM makes it really easy to play around with users and groups in AD!
Update: if you need to loop through all the users of a domain - try 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
UserPrincipal qbeUser = new UserPrincipal(ctx);
// create your principal searcher passing in the QBE principal
PrincipalSearcher srch = new PrincipalSearcher(qbeUser);
// find all matches
foreach(var found in srch.FindAll())
{
UserPrincipal user = found as UserPrincipal;
if(user != null)
{
// do whatever here
var usersSid = user.Sid;
// not sure what you mean by "username" - the "DisplayName" ?
var username = user.DisplayName;
var userSamAccountName = user.SamAccountName;
}
}
Update #2: if you can't (or don't want to) use the S.DS.AM approach - which is the easiest, for Active Directory, by far - then you need to fall back to the System.DirectoryServices classes and methods:
// define the root of your search
DirectoryEntry root = new DirectoryEntry("LDAP://dc=YourCompany,dc=com");
// set up DirectorySearcher
DirectorySearcher srch = new DirectorySearcher(root);
srch.Filter = "(objectCategory=Person)";
srch.SearchScope = SearchScope.Subtree;
// define properties to load
srch.PropertiesToLoad.Add("objectSid");
srch.PropertiesToLoad.Add("displayName");
// search the directory
foreach(SearchResult result in srch.FindAll())
{
// grab the data - if present
if(result.Properties["objectSid"] != null && result.Properties["objectSid"].Count > 1)
{
var sid = result.Properties["objectSid"][0];
}
if(result.Properties["displayName"] != null && result.Properties["displayName"].Count > 0)
{
var userName = result.Properties["displayName"][0].ToString();
}
}

Active Directory Search getting Object reference not set

The below code works on my local machine by returning the user's full name from Active Directory:
string principal = System.Web.HttpContext.Current.Request.LogonUserIdentity.Name.Remove(0, 12);
string filter = string.Format("(&(ObjectClass={0})(sAMAccountName={1}))", "person", principal);
string[] properties = new string[] { "fullname" };
DirectoryEntry adRoot = new DirectoryEntry("LDAP://myserver.com");
adRoot.AuthenticationType = AuthenticationTypes.Secure;
DirectorySearcher searcher = new DirectorySearcher(adRoot);
searcher.SearchScope = SearchScope.Subtree;
searcher.ReferralChasing = ReferralChasingOption.All;
searcher.PropertiesToLoad.AddRange(properties);
searcher.Filter = filter;
SearchResult result = searcher.FindOne();
DirectoryEntry directoryEntry = result.GetDirectoryEntry();
string displayName = directoryEntry.Properties["displayName"][0].ToString();
if (string.IsNullOrEmpty(displayName) == false)
{
return displayName;
}
When I publish it to the development server I get the following error:
System.NullReferenceException: Object reference not set to an instance
of an object.
The error is thrown on the following line:
DirectoryEntry directoryEntry = result.GetDirectoryEntry();
I have tried
DirectoryEntry adRoot = new DirectoryEntry("LDAP://" + domain, AdAdminUsername, AdAdminPassword, AuthenticationTypes.Secure);
but still no joy.
Any ideas?
Thanks!
Just from outside : your string called principal is built by the following :
string principal = System.Web.HttpContext.Current.Request.LogonUserIdentity.Name.Remove(0, 12);
Have you log 'System.Web.HttpContext.Current.Request.LogonUserIdentity.Name' on your dev server ? This static construction may be the begining of you troubles because if principal is'nt what you think it is, the result of FindOne may be NULL.
In your current code, you must check for NULL after the call to FindOne() - it could return a NULL value if no matching directory entry was found.
See the MSDN docs:
If more than one entry is found during the search, only the first
entry is returned. If no entries are found to match the search
criteria, a null reference (Nothing in Visual Basic) is returned.
Plus, you should also always check for the presence of a property before accessing it - it could be absent.....
Therefore, your code should be something like this:
SearchResult result = searcher.FindOne();
if(result != null)
{
DirectoryEntry directoryEntry = result.GetDirectoryEntry();
if(directoryEntry.Properties["displayName"] != null &&
directoryEntry.Properties["displayName"].Length > 0)
{
string displayName = directoryEntry.Properties["displayName"][0].ToString();
if (!string.IsNullOrEmpty(displayName))
{
return displayName;
}
}
}
But: if you're on .NET 3.5 or newer, you should check out the System.DirectoryServices.AccountManagement namespace which makes a lot of things a lot easier when dealing with Active Directory.
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.SamAccountName = "whatever you're looking for.....";
// 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.

Categories