How to retrieve DirectoryEntry from a DirectoryEntry and a DN - c#

I have a DirectoryEntry object representing a user. From the DirectoryEntry.Properties collection, I am retrieving the "manager" property, which will give me a Distinguished Name ("DN") value for the user's manager.
Can I retrieve a DirectoryEntry object for the manager from just these two objects? If so, how?
I'm envisioning something like DirectoryEntry.GetEntryFromDN(dnManager);, but I cannot find a similar call.
Just to clarify, the DirectoryEntry and DN are the only pieces of information I have. I cannot instantiate a new DirectoryEntry because then I would have have to either use the default Directory and credentials or have the Directory name/port and username/password.

DirectoryEntry User = YourPreExistingUser();
string managerDN = User.Properties["manager"][0].ToString();
// Browse up the object hierarchy using DirectoryEntry.Parent looking for the
// domain root (domainDNS) object starting from the existing user.
DirectoryEntry DomainRoot = User;
do
{
DomainRoot = DomainRoot.Parent;
}
while (DomainRoot.SchemaClassName != "domainDNS");
// Use the domain root object we found as the search root for a DirectorySearcher
// and search for the manager's distinguished name.
using (DirectorySearcher Search = new DirectorySearcher())
{
Search.SearchRoot = DomainRoot;
Search.Filter = "(&(distinguishedName=" + managerDN + "))";
SearchResult Result = Search.FindOne();
if (Result != null)
{
DirectoryEntry Manager = Result.GetDirectoryEntry();
}
}

You can create a new DirectoryEntry instance providing the the DN as argument and then
attempt to bind (by refreshing properties for example).
DirectoryEntry e = new DirectoryEntry(dn, "u", "p");
e.RefreshCache();

Related

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

Active Directory - Get Manager account (from Distinguished Name)

I am trying to get the manager's account for a user account in active directory.
Here's the code I have..
using System.DirectoryServices;
using System.DirectoryServices.ActiveDirectory;
DirectoryContext directoryContext = new DirectoryContext(DirectoryContextType.Domain, "MyDomain");
Domain domain = Domain.GetDomain(directoryContext);
// Find MY directory Entry
DirectorySearcher search = new DirectorySearcher(domain.GetDirectoryEntry())
{
Filter = String.Format("(SAMAccountName={0})", "<my user id>")
};
search.PropertiesToLoad.Add("displayName");
search.PropertiesToLoad.Add("mail");
search.PropertiesToLoad.Add("manager");
DirectoryEntry userAccount = search.FindOne()?.GetDirectoryEntry();
As you can see, there's a property called manager that is requested and comes back as
CN=Manager Name,OU=Employee,OU=United Kingdom, OU=CompantUsers, DC=MyDomain, DC=xxx,DC=zzzzz
The CN=Manager Name is the full name, not the LoginID/SAMAccountName (as used when I searched for MY AD entry ... so how can I now find the AD entry for my manager
Ahhh ... When you know the right question to ask then Google knows the answer ... I did not know that the CN..... string was known as a distinguishedName
if (userAccount.Properties["manager"].Value != null)
{
DirectorySearcher search2 = new DirectorySearcher(domain.GetDirectoryEntry())
{
Filter = string.Format("(distinguishedName={0})", userAccount.Properties["manager"].Value)
};
search2.PropertiesToLoad.Add("displayName");
search2.PropertiesToLoad.Add("mail");
search2.PropertiesToLoad.Add("manager");
DirectoryEntry mgrAcc = search2.FindOne()?.GetDirectoryEntry();
}

Updating Active Directory User Logon Name Domain

Currently working on automating creation of Active Directory users, but I cannot figure out how to update the field indicated in the linked image. (I can't attach images because I have fewer than 10 posts) image
I can update the user logon name by (userprincipal being an instance of the userprincipal object set to the appropriate user):
userPrincipal.UserPrincipalName = logonName
and I can update other similar user properties such as job title by (user location being an instance of directoryentry that points to the directory location of the user):
(userLocation.Properties["title"]).Value = title;
But no matter what I try and adjust, I haven't been able to figure out how to update that particular field. Any help is greatly appreciated!
You must know the property name before you can set it.
there can be 100s and 100s of properties in the active directory some being set from the user interface and some being set from somewhere else, whatever
you can check for the properties name by doing the following
DirectoryEntry directoryEntry = new DirectoryEntry(ConnectionString, ProviderUserName, ProviderPassword, AuthenticationTypes.Secure);
/******************************/
DirectorySearcher search = new DirectorySearcher(directoryEntry);
search.Filter = "(&(objectClass=user)(sAMAccountName=" + username + "))";
search.CacheResults = false;
SearchResultCollection allResults = search.FindAll();
StringBuilder sb = new StringBuilder();
foreach (SearchResult searchResult in allResults)
{
foreach (string propName in searchResult.Properties.PropertyNames)
{
ResultPropertyValueCollection valueCollection = searchResult.Properties[propName];
foreach (Object propertyValue in valueCollection)
{
sb.AppendLine(string.Format("property:{0}, value{1}<br />", propName, propertyValue));
}
}
}
return sb.ToString();
this will result in all the active directory for some user you provide
after that you will be able to set all the properties that you want because you have the property name which is available for the user

get windows users with group name using C# [duplicate]

I have a ASP.NET Website project and I need to list all the users and their groups on my Windows system. I have set the identity impersonation to true and provided the username and password of the admin in the web.config. Where do I start?
Thanks in advance.
Update:
I have the following code at the moment -
var machine = new DirectoryEntry("WinNT://<IP ADDRESS>");
foreach (DirectoryEntry child in machine.Children)
{
// get the child's group(s).
}
When I debug, I can see the list of users in machine.Children. How do I find the group(s) that this user belongs to?
This article covers how to talk to Active Directory and should get you where you want to go:
http://www.codeproject.com/KB/system/everythingInAD.aspx
To get users, you would do something like this:
public List<string> GetUserList()
{
string DomainName="";
string ADUsername="";
string ADPassword="";
List<string> list=new List<string>();
DirectoryEntry entry=new DirectoryEntry(LDAPConnectionString, ADUsername, ADPassword);
DirectorySearcher dSearch=new DirectorySearcher(entry);
dSearch.Filter="(&(objectClass=user))";
foreach(SearchResult sResultSet in dSearch.FindAll())
{
string str=GetProperty(sResultSet, "userPrincipalName");
if(str!="")
list.Add(str);
}
return list;
}
You probably want to start with the DirectoryEntry and Active Directory support in .net.
Here's a good resource: http://www.codeproject.com/KB/system/everythingInAD.aspx
Local access is similar, even if you're not in a domain:
DirectoryEntry localMachine = new DirectoryEntry("WinNT://" +
Environment.MachineName);
DirectoryEntry admGroup = localMachine.Children.Find("administrators",
"group");
object members = admGroup.Invoke("members", null);
foreach (object groupMember in (IEnumerable)members) {
DirectoryEntry member = new DirectoryEntry(groupMember);
//...
}

Connect to Active Directory via LDAP

I want to connect to our local Active Directory with C#.
I've found this good documentation.
But I really don't get how to connect via LDAP.
Can somebody of you explain how to use the asked parameters?
Sample Code:
static DirectoryEntry createDirectoryEntry()
{
// create and return new LDAP connection with desired settings
DirectoryEntry ldapConnection = new DirectoryEntry("rizzo.leeds-art.ac.uk");
ldapConnection.Path = "LDAP://OU=staffusers,DC=leeds-art,DC=ac,DC=uk";
ldapConnection.AuthenticationType = AuthenticationTypes.Secure;
return ldapConnection;
}
I just have the Hostname and the IP Address of our Active Directory Server. What does DC=xxx,DC=xx and so on mean?
DC is your domain. If you want to connect to the domain example.com than your dc's are: DC=example,DC=com
You actually don't need any hostname or ip address of your domain controller (There could be plenty of them).
Just imagine that you're connecting to the domain itself. So for connecting to the domain example.com you can simply write
DirectoryEntry directoryEntry = new DirectoryEntry("LDAP://example.com");
And you're done.
You can also specify a user and a password used to connect:
DirectoryEntry directoryEntry = new DirectoryEntry("LDAP://example.com", "username", "password");
Also be sure to always write LDAP in upper case. I had some trouble and strange exceptions until I read somewhere that I should try to write it in upper case and that solved my problems.
The directoryEntry.Path Property allows you to dive deeper into your domain. So if you want to search a user in a specific OU (Organizational Unit) you can set it there.
DirectoryEntry directoryEntry = new DirectoryEntry("LDAP://example.com");
directoryEntry.Path = "LDAP://OU=Specific Users,OU=All Users,OU=Users,DC=example,DC=com";
This would match the following AD hierarchy:
com
example
Users
All Users
Specific Users
Simply write the hierarchy from deepest to highest.
Now you can do plenty of things
For example search a user by account name and get the user's surname:
DirectoryEntry directoryEntry = new DirectoryEntry("LDAP://example.com");
DirectorySearcher searcher = new DirectorySearcher(directoryEntry) {
PageSize = int.MaxValue,
Filter = "(&(objectCategory=person)(objectClass=user)(sAMAccountName=AnAccountName))"
};
searcher.PropertiesToLoad.Add("sn");
var result = searcher.FindOne();
if (result == null) {
return; // Or whatever you need to do in this case
}
string surname;
if (result.Properties.Contains("sn")) {
surname = result.Properties["sn"][0].ToString();
}
ldapConnection is the server adres: ldap.example.com
Ldap.Connection.Path is the path inside the ADS that you like to use insert in LDAP format.
OU=Your_OU,OU=other_ou,dc=example,dc=com
You start at the deepest OU working back to the root of the AD, then add dc=X for every domain section until you have everything including the top level domain
Now i miss a parameter to authenticate, this works the same as the path for the username
CN=username,OU=users,DC=example,DC=com
Introduction to LDAP
If your email address is 'myname#mydomain.com', try changing the createDirectoryEntry() as below.
XYZ is an optional parameter if it exists in mydomain directory
static DirectoryEntry createDirectoryEntry()
{
// create and return new LDAP connection with desired settings
DirectoryEntry ldapConnection = new DirectoryEntry("myname.mydomain.com");
ldapConnection.Path = "LDAP://OU=Users, OU=XYZ,DC=mydomain,DC=com";
ldapConnection.AuthenticationType = AuthenticationTypes.Secure;
return ldapConnection;
}
This will basically check for com -> mydomain -> XYZ -> Users -> abcd
The main function looks as below:
try
{
username = "Firstname LastName"
DirectoryEntry myLdapConnection = createDirectoryEntry();
DirectorySearcher search = new DirectorySearcher(myLdapConnection);
search.Filter = "(cn=" + username + ")";
....

Categories