Directory Searcher - Searching multiple OU's - c#

I'm currently working on a project where i have to pull some Active Directory information on all our servers.
The thing is i ONLY wan't the servers in AD, and not all the desktop computers.
The servers are located in multiple sub directories, for each location.
I was able to filter on operating system like this, but as some of them are cluster servers AD havn't picked up the OS of the ones hosted on those so I need to create a filter or some logic that only looks in the OU's called Servers.
This is what i currently have:
DirectoryEntry entry = new DirectoryEntry(path);
// Create a DirectorySearcher object.
DirectorySearcher mySearcher = new DirectorySearcher(entry);
// Set a filter for users with the name test.
// Search specific computer replace OperatingSystem=Windows*Server* with anr=<servername>
mySearcher.Filter = "(&(objectClass=computer)(OperatingSystem=Windows*Server*))";
mySearcher.SearchScope = SearchScope.Subtree;
results = mySearcher.FindAll();
mySearcher.PropertiesToLoad.Add("cn");
mySearcher.PropertiesToLoad.Add("dnshostname");
mySearcher.PropertiesToLoad.Add("Site");
mySearcher.PropertiesToLoad.Add("Description");
mySearcher.PropertiesToLoad.Add("Location");
mySearcher.PropertiesToLoad.Add("operatingsystem");
mySearcher.PropertiesToLoad.Add("operatingsystemservicepack");
mySearcher.PropertiesToLoad.Add("operatingsystemversion");
mySearcher.PropertiesToLoad.Add("managedBy");
con.Open();
foreach (SearchResult searchResult in results)
{
cmd.Parameters.AddWithValue("#Servername", Convert.ToString(searchResult.GetDirectoryEntry().Properties["cn"].Value));
cmd.Parameters.AddWithValue("#DNSHostname", Convert.ToString(searchResult.GetDirectoryEntry().Properties["dnshostname"].Value));
cmd.Parameters.AddWithValue("#Description", Convert.ToString(searchResult.GetDirectoryEntry().Properties["description"].Value));
cmd.Parameters.AddWithValue("#Site", Convert.ToString(searchResult.GetDirectoryEntry().Properties["Site"].Value));
cmd.Parameters.AddWithValue("#Location", Convert.ToString(searchResult.GetDirectoryEntry().Properties["Location"].Value));
cmd.Parameters.AddWithValue("#OS", Convert.ToString(searchResult.GetDirectoryEntry().Properties["operatingsystem"].Value));
cmd.Parameters.AddWithValue("#OSServicePack", Convert.ToString(searchResult.GetDirectoryEntry().Properties["operatingsystemservicepack"].Value));
cmd.Parameters.AddWithValue("#OSVersion", Convert.ToString(searchResult.GetDirectoryEntry().Properties["operatingsystemversion"].Value));
cmd.Parameters.AddWithValue("#ManagedBy", Convert.ToString(searchResult.GetDirectoryEntry().Properties["managedBy"].Value));
if (searchResult.Path.Contains("OU=Test") == true)
{
cmd.Parameters.AddWithValue("#IsTestServer", 1);
}
else
{
cmd.Parameters.AddWithValue("#IsTestServer", 0);
}
cmd.ExecuteNonQuery();
cmd.Parameters.Clear();
}
}

After some more search today i found the solution here on the website
get computer from OU

Related

DirectorySearcher working in Local but not working in IIS server

I want to list the all mail list or search a mail id present in my Active directory so I have used the DirectorySearcher like following and working in my local system if I run it via visual studio but not working when I publish or deploy these code to an IIS server.
My C# Code,
[HttpGet]
public JsonResult getADEmail(string query = "")
{
DirectorySearcher dirSearcher = new DirectorySearcher();
dirSearcher.Filter = "(&(objectClass=user)(objectcategory=person)(mail=" + query + "*))";
SearchResult srEmail = dirSearcher.FindOne();
SearchResultCollection SearchResultCollection = dirSearcher.FindAll();
string propName = "mail";
ResultPropertyValueCollection valColl = srEmail.Properties[propName];
List<string> results = new List<string>();
foreach (SearchResult sr in SearchResultCollection)
{
ResultPropertyValueCollection val = sr.Properties[propName];
results.Add(val[0].ToString());
}
return Json(results);
}
Directory Path in my local,
"LDAP://DC=arcadis-nl,DC=local" from (dirSearcher.SearchRoot.Path)
The IIS is on another server: 154:139:1:150
Where I did go wrong?What should I do to resolve this issue?.
It seems like a directory permissions problem.Few things to check:
Does the user (or machine) that is connecting to the IIS server have permissions to perform the query?
In these kind of scenario , we have to set the identity of the application pool to a user who has access to the directory.
Additional reference:
https://www.codeproject.com/Tips/599697/Get-list-of-Active-Directory-users-in-Csharp
Hope it helps.

How to get users from Active Directory in C# and display them in a ComboBox

I'm trying to show, in a ComboBox control, the users from an Active Directory on the network. To do this, I've the next function:
public static List<Usuario> MostrarUsuariosDominio()
{
List<Usuario> rst = new List<Usuario>();
try
{
DirectoryContext dc = new DirectoryContext(DirectoryContextType.Domain, Environment.UserDomainName);
Domain domain = Domain.GetDomain(dc);
DirectoryEntry de = domain.GetDirectoryEntry();
DirectorySearcher adSearcher = new DirectorySearcher(de);
adSearcher.Filter = "(&(objectClass=user)(objectCategory=person))";
adSearcher.PropertiesToLoad.Add("samaccountname");
SearchResult result;
SearchResultCollection iResult = adSearcher.FindAll();
Usuario item;
if (iResult != null)
{
for (int counter = 0; counter < iResult.Count; counter++)
{
result = iResult[counter];
if (result.Properties.Contains("samaccountname"))
{
item = new Usuario();
item.Nombre = (String)result.Properties["samaccountname"][0];
rst.Add(item);
}
}
}
adSearcher.Dispose();
}
catch (Exception ex)
{
Usuario item = new Usuario();
item.Nombre = "No se pudo recuperar la lista de usuarios";
rst.Add(item);
}
return rst;
}
If I run the application in the PC who's domain controller it works fine: the function returns to me all users. But if I run it on another PC, I get the exception:
Specified domain does not exist or couldn't contact with it
Is there any way to recover the users list from another PC?
This line:
DirectoryContext dc = new DirectoryContext(DirectoryContextType.Domain, Environment.UserDomainName);
Tells it to connect to the domain that the current user is logged into. Are you logged in as a domain user?
Maybe check what Environment.UserDomainName is equal to and see if it is right.
If it's right, then it may be a network issue - it can't talk to the domain. Do you need to be connected to VPN?
To get all the users in a Active Directory domain you can use an DirectorySearcher class object to querie to a domain about all the users availables in that domain.
The class DirectorySearcher is contained in System.DirectoryServices namespace and is a class to perform queries against Active Directory Domain Services.
In this page is an example about how to do it:
...
string DomainPath = "LDAP://DC=xxxx,DC=com"
DirectoryEntry searchRoot = new DirectoryEntry(DomainPath);
DirectorySearcher search = new DirectorySearcher(searchRoot);
search.Filter = "(&(objectClass=user)(objectCategory=person))";
search.PropertiesToLoad.Add("samaccountname");
search.PropertiesToLoad.Add("mail");
search.PropertiesToLoad.Add("usergroup");
search.PropertiesToLoad.Add("displayname");//first name
SearchResultCollection resultCol = search.FindAll();
...
In DirectorySearcher, create a DirectorySearcher object which searches
for all users in a domain. search.Filter = "(&(objectClass=user)(objectCategory=person))" filters the search.
The search filter syntax looks a bit complicated, but basically it
filters the search results to only include users -> "objectCategory=person" and "objectClass=user" - and excludes disabled
user accounts by performing a bitwise AND of the userAccountControl
flags and the "account disabled" flag.
To point to the local Active Directory domain you can use this:
DirectoryEntry searchRoot = new DirectoryEntry("WinNT://" + Environment.MachineName);
You can combine that example with this code that uses foreach instead of use the for loop in the page example:
foreach (SearchResult result in resultCol)
{
yourComboBox.Items.Add(result.Properties["displayname"]);
}
I left here some pages from the Microsoft MSDN and codeproject.com sites:
DirectorySearcher Class
Get List of Active Directory Users in C#
SearchResultCollection Class
SearchResult Class
SearchResult.Properties Property

Different result with DirectorySearcher

I wrote a small app to check AD group members. When I execute the following code on my pc, It works well, the SearchResult contains the "member" property, however when I run the same exe on the server or on an another computer the "member" property is missing. The usnchanged and usncreated will be different also. I run the exe with the same user on every pc. What can cause this?
...
using (DirectorySearcher searcher = new DirectorySearcher())
{
searcher.CacheResults = false;
searcher.Filter = "(&(objectClass=group)(cn=" + ADName + "))";
searcher.SizeLimit = int.MaxValue;
searcher.PageSize = int.MaxValue;
if (!DirectoryEntry.Exists(ADPath))
{
return null;
}
searcher.SearchRoot = new DirectoryEntry(ADPath);
using (SearchResultCollection collection = searcher.FindAll())
{
if (collection.Count == 1)
{
return collection[0];
}
}
}
...
The group membership data is not replicated to the global catalog. The query might work sometimes, if you happen to connect to the domain controller with the actual membership data. On other machines, you probably connect to other domain controllers, of different domains, where the information is not available.
You might want to connect to a domain controller in the actual domain, not to the global catalog.

Loading the active directory user and their associated Computers

Hello Everyone i am trying to develop a program that will list will all the user of Active Directory and when i select one user the program should be able to show the computers associated with that user. i.e the Computers that are accessible to that AD user.
I have written code to list all user but no idea how to list the computers associated with that user.
Here is my code to load AD User into datatable:
DataTable dtUser= new DataTable();
try
{
DirectoryEntry dom = Domain.GetComputerDomain().GetDirectoryEntry();
DirectorySearcher dsAllUsers = new DirectorySearcher(dom);
dsAllUsers.SearchScope = SearchScope.Subtree;
dsAllUsers.Filter = "(objectCategory=Person)";
SearchResultCollection result = dsAllUsers.FindAll();
dtUser.Columns.Add("CustodianName");
dtUser.Columns.Add("Email");
dtUser.Columns.Add("Title");
dtUser.Columns.Add("Dept.");
foreach (SearchResult rs in result)
{
DataRow newRow = dtUser.NewRow();
if (rs.GetDirectoryEntry().Properties["samaccountname"].Value != null)
newRow["CustodianName"] = rs.GetDirectoryEntry().Properties["samaccountname"].Value.ToString();
if (rs.GetDirectoryEntry().Properties["mail"].Value != null)
newRow["Email"] = rs.GetDirectoryEntry().Properties["mail"].Value.ToString();
if (rs.GetDirectoryEntry().Properties["title"].Value != null)
newRow["Title"] = rs.GetDirectoryEntry().Properties["title"].Value.ToString();
if (rs.GetDirectoryEntry().Properties["department"].Value != null)
newRow["Dept."] = rs.GetDirectoryEntry().Properties["department"].Value.ToString();
dtUser.Rows.Add(newRow);
}
return dtUser;
}
catch (Exception)
{
throw;
}
I don't believe standard LDAP/Active Directory has anything like this.
Computers are just another class of AD objects - but there's no "link" between a user and one (or multiple) computer(s) - there's no belongsTo attribute on the computer class, nor is there a computers collection on User.
If your organization has implemented an extension to the default AD schema (which is entirely possible!), it's a custom solution, and then you must know what it is! :-)

Directory Services, Search all available providers

I have the following method used for searching for a User Group either on the local computer (done first) or in the Current Forest.
public string FindUserGroup(string group)
{
//Search local computer
using (DirectorySearcher searcher = new DirectorySearcher(new DirectoryEntry()))
{
searcher.Filter = "(&(objectClass=group)(|(cn=" + group + ")(dn=" + group + ")))";
SearchResult result = searcher.FindOne();
if (result != null)
return TranslateDirectoryEntryPath(result.GetDirectoryEntry().Path);
}
//Search current forest
Forest forest = Forest.GetCurrentForest();
foreach (Domain domain1 in forest.Domains)
{
using (DirectorySearcher searcher = new DirectorySearcher(domain1.GetDirectoryEntry()))
{
searcher.Filter = "(&(objectClass=group)(|(cn=" + group + ")(dn=" + group + ")))";
SearchResult result = searcher.FindOne();
if (result != null)
return TranslateDirectoryEntryPath(result.GetDirectoryEntry().Path);
}
}
return string.Empty;
}
My problem is that we as an example have say "domain.local" and "mydomain.local", and my current login is bound to "domain.local", then using below won't be able to find anything in "mydomain.local", even if I through the Windows User Interface is able to.
How can I search all viewable providers from my computers perspective when I don't nessesarily know them all? Do I REALLY have to do the Registry Work my self?
Edit:
One difference in the 2 domains is the "level" they are on when I in an object browser dialog chooses "Locations", it layouts as:
Computer
Entire Direction
domain.local
mydomain.local
So "mydomain.local" excists outside what is referred to as "Entire Directory", yet my computer can locate it, if that makes any difference?
I don't see a problem as this code here would have already be binded to the other domains.
foreach (Domain domain1 in forest.Domains)
{
using (DirectorySearcher searcher = new DirectorySearcher(domain1.GetDirectoryEntry()))
{
Are you trying to say that later on you're binding a DirectoryEntry on your own, and you can't find objects from other domain?

Categories