Les autres réponses ont été mal décrits, ne décrit pas comment pour les implémenter, et la plupart ont donné les mauvaises propriétés de filtre. Vous ne même pas besoin d'utiliser .Filter
- vous pouvez simplement affecter vos propriétés (nom = .Surname
, prénom = .GivenName
) à un objet UserPrincipal
, puis recherchez sur cet objet en utilisant un PrincipalSearcher
en tout cas qui déclenche la recherche:
string firstName = txtFirstName.Text;
string lastName = txtLastName.Text;
PrincipalContext ctx = new PrincipalContext(ContextType.Domain);
UserPrincipal up = new UserPrincipal(ctx);
if (!String.IsNullOrEmpty(firstName))
up.GivenName = firstName;
if (!String.IsNullOrEmpty(lastName))
up.Surname = lastName;
PrincipalSearcher srch = new PrincipalSearcher(up);
srch.QueryFilter = up;
Je suppose que vous avez pour textboxes Prénom et nom pour l'obtenir, avec les ID/noms de txtFirstName
et txtLastName
. Notez que si vous n'avez pas de valeur dans la propriété que vous recherchez, ne l'ajoutez pas au UserPrincipal
, sinon cela entraînera une exception. C'est la raison des contrôles que j'ai inclus, ci-dessus.
Vous pouvez ensuite faire un .FindAll
sur srch
pour obtenir des résultats de recherche dans une collection PrincipalSearchResult
de Principal
objets:
using (PrincipalSearchResult<Principal> results = srch.FindAll())
{
if (results != null)
{
int resultCount = results.Count();
if (resultCount > 0) // we have results
{
foreach (Principal found in results)
{
string username = found.SamAccountName; // Note, this is not the full user ID! It does not include the domain.
}
}
}
}
Notez que les résultats ne seront pas nulle même si son .Count()
est 0
, et pourquoi les deux contrôles sont Là.
Vous itérer à l'aide que foreach
pour obtenir les propriétés dont vous avez besoin, et cela répond à la question de savoir comment trouver un utilisateur dans AD en utilisant C#, mais notez que vous ne pouvez obtenir à quelques propriétés en utilisant l'objet Principal
, et si je atteint cette question par Google (comme je l'ai fait), je serais très découragé. Si vous trouvez que c'est tout ce dont vous avez besoin - génial, vous avez terminé! Mais pour obtenir le repos (et reposer ma propre conscience), vous devez plonger, et je vais décrire comment faire cela.
J'ai trouvé que vous ne pouvez pas simplement utiliser que username
je mets ci-dessus, mais vous devez obtenir le type de nom entier DOMAIN\doej
. C'est comme ça que tu fais ça. , Mettre à la place cela dans cette boucle foreach
, au-dessus:
string userId = GetUserIdFromPrincipal(found);
et utilisez cette fonction:
private static string GetUserIdFromPrincipal(Principal prin)
{
string upn = prin.UserPrincipalName;
string domain = upn.Split('@')[1];
domain = domain.Substring(0, domain.IndexOf(".YOURDOMAIN"));
// "domain" will be the subdomain the user belongs to.
// This may require edits depending on the organization.
return domain + @"\" + prin.SamAccountName;
}
Une fois que vous avez, vous pouvez appeler cette fonction:
public static string[] GetUserProperties(string strUserName)
{
UserPrincipal up = GetUser(strUserName);
if (up != null)
{
string firstName = up.GivenName;
string lastName = up.Surname;
string middleInit = String.IsNullOrEmpty(up.MiddleName) ? "" : up.MiddleName.Substring(0, 1);
string email = up.EmailAddress;
string location = String.Empty;
string phone = String.Empty;
string office = String.Empty;
string dept = String.Empty;
DirectoryEntry de = (DirectoryEntry)up.GetUnderlyingObject();
DirectorySearcher ds = new DirectorySearcher(de);
ds.PropertiesToLoad.Add("l"); // city field, a.k.a location
ds.PropertiesToLoad.Add("telephonenumber");
ds.PropertiesToLoad.Add("department");
ds.PropertiesToLoad.Add("physicalDeliveryOfficeName");
SearchResultCollection results = ds.FindAll();
if (results != null && results.Count > 0)
{
ResultPropertyCollection rpc = results[0].Properties;
foreach (string rp in rpc.PropertyNames)
{
if (rp == "l") // this matches the "City" field in AD properties
location = rpc["l"][0].ToString();
if (rp == "telephonenumber")
phone = FormatPhoneNumber(rpc["telephonenumber"][0].ToString());
if (rp == "physicalDeliveryOfficeName")
office = rpc["physicalDeliveryOfficeName"][0].ToString();
if (rp == "department")
dept = rpc["department"][0].ToString();
}
}
string[] userProps = new string[10];
userProps[0] = strUserName;
userProps[1] = firstName;
userProps[2] = lastName;
userProps[3] = up.MiddleName;
userProps[4] = middleInit;
userProps[5] = email;
userProps[6] = location;
userProps[7] = phone;
userProps[8] = office;
userProps[9] = dept;
return userProps;
}
else
return null;
}
/// <summary>
/// Returns a UserPrincipal (AD) user object based on string userID being supplied
/// </summary>
/// <param name="strUserName">String form of User ID: domain\username</param>
/// <returns>UserPrincipal object</returns>
public static UserPrincipal GetUser(string strUserName)
{
PrincipalContext oPrincipalContext = new PrincipalContext(ContextType.Domain);
try
{
UserPrincipal oUserPrincipal = UserPrincipal.FindByIdentity(oPrincipalContext, strUserName);
return oUserPrincipal;
}
catch (Exception ex) { return null; }
}
public static string FormatPhoneNumber(string strPhoneNumber)
{
if (strPhoneNumber.Length > 0)
// return String.Format("{0:###-###-####}", strPhoneNumber); // formating does not work because strPhoneNumber is a string and not a number
return Regex.Replace(strPhoneNumber, @"(\d{3})(\d{3})(\d{4})", "$1-$2-$3");
else
return strPhoneNumber;
}
Notez que la fonction FormatPhoneNumber
est pour les numéros nord-américains. Il prendra un nombre qu'il trouve (##########
) et le séparera en ###-###-####
.
Vous pouvez alors obtenir les propriétés comme celui-ci, de retour dans cette boucle foreach
:
string[] userProps = GetUserProperties(userId);
string office = userProps[8];
Mais, comme une solution tout, vous pouvez même ajouter ces résultats dans une colonne DataRow
, et revenir comme partie d'un DataTable
que vous pourriez ensuite lier à un ListView
ou GridView
. Voici comment je l'ai fait, l'envoi d'un List<string>
rempli avec les propriétés que je avais besoin:
/// <summary>
/// Gets matches based on First and Last Names.
/// This function takes a list of acceptable properties:
/// USERNAME
/// MIDDLE_NAME
/// MIDDLE_INITIAL
/// EMAIL
/// LOCATION
/// POST
/// PHONE
/// OFFICE
/// DEPARTMENT
///
/// The DataTable returned will have columns with these names, and firstName and lastName will be added to a column called "NAME"
/// as the first column, automatically.
/// </summary>
/// <param name="firstName"></param>
/// <param name="lastName"></param>
/// <param name="props"></param>
/// <returns>DataTable of columns from "props" based on first and last name results</returns>
public static DataTable GetUsersFromName(string firstName, string lastName, List<string> props)
{
string userId = String.Empty;
int resultCount = 0;
DataTable dt = new DataTable();
DataRow dr;
DataColumn dc;
// Always set the first column to the Name we pass in
dc = new DataColumn();
dc.DataType = System.Type.GetType("System.String");
dc.ColumnName = "NAME";
dt.Columns.Add(dc);
// Establish our property list as columns in our DataTable
if (props != null && props.Count > 0)
{
foreach (string s in props)
{
dc = new DataColumn();
dc.DataType = System.Type.GetType("System.String");
if (!String.IsNullOrEmpty(s))
{
dc.ColumnName = s;
dt.Columns.Add(dc);
}
}
}
// Start our search
PrincipalContext ctx = new PrincipalContext(ContextType.Domain);
UserPrincipal up = new UserPrincipal(ctx);
if (!String.IsNullOrEmpty(firstName))
up.GivenName = firstName;
if (!String.IsNullOrEmpty(lastName))
up.Surname = lastName;
PrincipalSearcher srch = new PrincipalSearcher(up);
srch.QueryFilter = up;
using (PrincipalSearchResult<Principal> results = srch.FindAll())
{
if (results != null)
{
resultCount = results.Count();
if (resultCount > 0) // we have results
{
foreach (Principal found in results)
{
// Iterate results, set into DataRow, add to DataTable
dr = dt.NewRow();
dr["NAME"] = found.DisplayName;
if (props != null && props.Count > 0)
{
userId = GetUserIdFromPrincipal(found);
// Get other properties
string[] userProps = GetUserProperties(userId);
foreach (string s in props)
{
if (s == "USERNAME")
dr["USERNAME"] = userId;
if (s == "MIDDLE_NAME")
dr["MIDDLE_NAME"] = userProps[3];
if (s == "MIDDLE_INITIAL")
dr["MIDDLE_INITIAL"] = userProps[4];
if (s == "EMAIL")
dr["EMAIL"] = userProps[5];
if (s == "LOCATION")
dr["LOCATION"] = userProps[6];
if (s == "PHONE")
dr["PHONE"] = userProps[7];
if (s == "OFFICE")
dr["OFFICE"] = userProps[8];
if (s == "DEPARTMENT")
dr["DEPARTMENT"] = userProps[9];
}
}
dt.Rows.Add(dr);
}
}
}
}
return dt;
}
Vous appelez cette fonction comme ceci:
string firstName = txtFirstName.Text;
string lastName = txtLastName.Text;
List<string> props = new List<string>();
props.Add("OFFICE");
props.Add("DEPARTMENT");
props.Add("LOCATION");
props.Add("USERNAME");
DataTable dt = GetUsersFromName(firstName, lastName, props);
Le DataTable
sera rempli de ces colonnes, et une colonne NAME
en tant que première colonne, qui aura le .DisplayName
réel de l'utilisateur de AD.
Note: Vous devez faire référence System.DirectoryServices
et System.DirectoryServices.AccountManagement
, System.Text.RegularExpressions
, System.Data
à utiliser tout cela.
HTH!
Les réponses ci-dessous sont tous sur l'utilisation du sAMAccountName, et je ne sais pas pourquoi ils ont tant de upvotes. Cette question concerne l'utilisation du prénom et du nom pour obtenir des propriétés! Seule la réponse correcte supérieure/marquée est même proche. – vapcguy