使用 C# 通过员工 ID 查询 Active Directory 中的用户电子邮件

Querying Active Directory using C# for user email by employee ID

是否可以使用 employeenumber 作为查询词从 Active Directory 中获取用户的电子邮件?

我正在使用 C# System.DirectoryServices 并且有点迷茫。我公司以前的开发人员正在使用这个过程,但他有一封电子邮件,正在查询员工编号。我已经把它改成了我认为应该的样子,但老实说,我不太理解代码。

我的代码有问题吗?每次我 运行 它时,我都会在 DirectoryEntry up_user = 行收到空引用错误。我认为这是因为上一行没有得到任何实体。

此外,关于这个主题有什么好的文档吗?到处都是 2011 年或 2013 年的帖子。

我有以下内容:

try
{
    string email = string.Empty;
    ContextType authenticationType = ContextType.Domain;
    PrincipalContext principalContext = new PrincipalContext(authenticationType, "MATRIC");
    UserPrincipal userPrincipal = null;

    userPrincipal = UserPrincipal.FindByIdentity(principalContext, empnum);

    DirectoryEntry up_User = (DirectoryEntry)userPrincipal.GetUnderlyingObject();
    DirectorySearcher deSearch = new DirectorySearcher(up_User);
    SearchResultCollection results = deSearch.FindAll();
    if (results != null && results.Count > 0)
    {
        ResultPropertyCollection rpc = results[0].Properties;
        foreach (string rp in rpc.PropertyNames)
        {
            if (rp == "mail") 
            {
                email = rpc["mail"][0].ToString();
            }
        }

        if (email != string.Empty)
        {
            return email;
        }

        return null;
    }
            return null;
}
catch (Exception ex)
{
    throw ex;
}

UserPrincipal.FindByIdentity 仅适用于根据 AD 认为的识别属性查找用户。这些列在 IdentityType 枚举中。员工编号不是其中之一。

您在 AD 中使用 employeeIdemployeeNumber 吗?它们是不同的属性,尽管它们都只是字符串,在 AD 中没有特殊含义或限制。

employeeId 属性在 UserPrincipal class 中公开,因此您可以按照 the answer here 中所述使用 UserPrincipal 进行搜索:

UserPrincipal searchTemplate = new UserPrincipal(principalContext);
searchTemplate.EmployeeID = employeeId;
PrincipalSearcher ps = new PrincipalSearcher(searchTemplate);

UserPrincipal user = (UserPrincipal)ps.FindOne();

然后您可以使用您找到的帐户的 EmailAddress 属性(您不需要使用 DirectorySearcher 执行您正在执行的操作)。

var emailAddress user?.EmailAddress;

如果您使用 employeeNumber,则需要使用 DirectorySearcher 才能找到它。像这样:

var search = new DirectorySearcher(new DirectoryEntry("LDAP://yourdomain.com"));
search.Filter = $"(&(ObjectClass=user)(employeeNumber={employeeNumber}))"; 
search.PropertiesToLoad.Add("mail");

var result = search.FindOne();
string emailAddress = null;
if (result.Properties.Contains("mail")) {
    emailAddress = result.Properties["mail"][0].Value as string;
}