을, 방법에 대해서는 설명하지 않았다 그들을 구현하고, 대부분은 잘못된 필터 속성을 부여했습니다. .Filter
을 사용할 필요조차 없습니다. 속성 (성 : .Surname
, 이름 = .GivenName
)을 UserPrincipal
개체에 할당 한 다음 검색을 트리거하는 모든 이벤트에서 PrincipalSearcher
을 사용하여 해당 개체를 검색 할 수 있습니다.
내가 믿고있어
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;
당신은 txtFirstName
및 txtLastName
의 ID/이름으로, 그걸 얻기 위해 첫 번째와 마지막 이름에 대한 텍스트 상자가 있습니다. 찾고있는 속성에 값이없는 경우 UserPrincipal
에 값을 추가하지 않으면 예외가 발생합니다. 그것이 위의 수표에 대한 이유입니다. 그 .Count()
모두 검사가 왜 0
, 그리고 경우에도 결과가 null 수 없음을
가
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.
}
}
}
}
참고 :
당신은 다음 PrincipalSearchResult
Principal
오브젝트의 콜렉션으로 검색 결과를 얻을 수 srch
에 .FindAll
을 그곳에.
foreach
을 사용하여 반복적으로 필요한 속성을 얻으십시오. 그러면 C#을 사용하여 AD에서 사용자를 찾는 방법에 대한 질문에 대답하지만 Principal
개체를 사용하는 몇 가지 속성 만 사용할 수 있습니다. Google을 통해이 질문에 도달했을 때 (나는 그랬던 것처럼) 매우 낙담 할 것입니다. 그게 당신이 필요로하는 모든 것을 발견했다면 - 끝났습니다! 그러나 나머지를 얻고 (그리고 내 자신의 양심을 쉬기 위해서), 당신은 잠수해야하며, 나는 그것을 어떻게하는지 설명 할 것입니다.
위의 내용을 username
으로 바꿀 수는 없지만 전체 이름은 DOMAIN\doej
이어야합니다. 이것이 당신이하는 방법입니다. 이 기능을 사용하면 것을 일단
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;
}
, 당신은 호출 할 수 있습니다 : 대신, 위, 그 foreach
루프에 넣고 :
string userId = GetUserIdFromPrincipal(found);
이 기능을 사용
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;
}
주를이 FormatPhoneNumber
기능은 북미 번호 용입니다. 발견 된 번호 (##########
)를 받아이를 ###-###-####
으로 분리하십시오.
string[] userProps = GetUserProperties(userId);
string office = userProps[8];
을하지만, 전체 솔루션으로, 당신은 DataRow
열에 결과를 추가도 할 수 있고,로 반환 :
그런 다음 해당 foreach
루프 다시,이 같은 특성을 얻을 수 있습니다 DataTable
의 일부로 다음 ListView
또는 GridView
에 바인딩 할 수 있습니다.
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);
DataTable
는, 그 열이 작성되며 :이 같은이 함수를 호출 할
/// <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;
}
이 내가 필요로하는 특성을 가득 List<string>
에 전송, 그것을 어떻게입니다 첫 번째 열로 NAME
열을 입력하면 AD에서 사용자의 실제 .DisplayName
이됩니다.
참고 : 당신은 System.DirectoryServices
및 System.DirectoryServices.AccountManagement
, System.Text.RegularExpressions
, System.Data
이 모든 사용 참조해야합니다.
HTH!
답변을 읽고있는 모든 SAMAccountName을 사용, 그들이 그렇게 많은 upvotes을 왜 모르겠어요 약 : 그 이유. 이 질문은 성과 이름을 사용하여 속성을 얻는 것에 관한 것입니다! 상단/표시된 정답만이 닫힙니다. – vapcguy