How to retrieve SAMAccountName from Active Directory
active-directory, c#, directoryservices
Solution
First off: `Domain\Administrator` is NOT a SAM account name! The SAM account name is a unique (over the whole domain) name of up to 20 characters in length - typically it's your "Windows user name" (e.g. `Administrator`) - but it does NOT include the domain name. That value made up of `domain\username` is NOT stored in Active Directory anywhere!
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
PrincipalContext ctx = new PrincipalContext(ContextType.Domain);
// find a user
UserPrincipal user = UserPrincipal.FindByIdentity(ctx, "SomeUserName");
if(user != null)
{
// do something here....
string samAccountName = user.SamAccountName;
}
The new S.DS.AM makes it really easy to play around with users and groups in AD!
If you want to search for a whole group of users (or groups or computers), 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 last name (Surname) of "Miller"
UserPrincipal qbeUser = new UserPrincipal(ctx);
qbeUser.Surname = "Miller";
// 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.....
}
Problem
I implemented a method that returns a list of Active Directory users, I would like to retrieve SAMAccountName like this `Domain\Administrator`. This is the method I use: ``` public Collection<software_user> GetUsersFromAD(String adConnectionString) { var users = new Collection<software_user>(); using (var directoryEntry = new DirectoryEntry(adConnectionString)) { var directorySearcher = new DirectorySearcher(directoryEntry); directorySearcher.Filter = "(&(objectClass=user))"; var propertiesToLoad = new[] { "SAMAccountName", "displayName", "givenName", "sn", "mail", "userAccountControl", "objectSid" }; directorySearcher.PropertiesToLoad.AddRange(propertiesToLoad); foreach (SearchResult searchEntry in directorySearcher.FindAll()) { var userEntry = searchEntry.GetDirectoryEntry(); var ldapUser = new software_user(); ldapUser.User_name = NullHandler.GetString(userEntry.Properties["displayName"].Value); if (string.IsNullOrEmpty(ldapUser.User_name)) continue; ldapUser.User_name = NullHandler.GetString(userEntry.Properties["SAMAccountName"].Value); ldapUser.email = NullHandler.GetString(userEntry.Properties["mail"].Value); ldapUser.user_shortname = NullHandler.GetString(userEntry.Properties["givenName"].Value); var userAccountControl = (int)userEntry.Properties["userAccountControl"].Value; //ldapUser.IsActive = (userAccountControl & UF_ACCOUNTDISABLE) != UF_ACCOUNTDISABLE; var sid = new SecurityIdentifier((byte[])userEntry.Properties["objectSid"][0], 0).Value; //ldapUser.SId = sid; users.Add(ldapUser); } } return users; } ```