Introduction
I recently had a project where I needed to convert the UMDS Authentication/Authorization to Active Directory (AD). I found the following link very useful for my migration from UMDS to AD.
During the code migration, I come to know that there is no direct way to get an extension attribute for users from Active Directory.
For those not familiar, when you install Exchange, it adds new attributes to your forest to the Person
class named “extensionAttribute1
” through “extensionAttribute15
”. You can see that in the following screen shot from my test domain. Aside from these Extension Attributes, there are many other attributes that are not directly accessible in UserPrincipal (System.DirectoryServices.AccountManagement
).
Background
If you're on .NET 3.5 and up and using the <font face="Courier New">System.DirectoryServices.AccountManagement</font>
(S.DS.AM) namespace, you can easily extend the existing <font face="Courier New">UserPrincipal</font>
class to get at more advanced properties, like Extension Attributes (named “extensionAttribute1
” through “extensionAttribute15
”) or other company specific attributes.
Using the Code
Basically, you just define a derived class based on <font face="Courier New">UserPrincipal</font>
, and then you define your additional properties you want:
namespace Helper
{
[DirectoryRdnPrefix("CN")]
[DirectoryObjectClass("Person")]
public class UserPrincipalEx : UserPrincipal
{
public UserPrincipalEx(PrincipalContext context)
: base(context)
{ }
public UserPrincipalEx(PrincipalContext context,
string samAccountName,
string password,
bool enabled)
: base(context, samAccountName, password, enabled)
{ }
[DirectoryProperty("ExtensionAttributeName")]
public string ExtensionAttributeName
{
get
{
if (ExtensionGet("ExtensionAttributeName").Length != 1)
return string.Empty;
return (string)ExtensionGet("ExtensionAttributeName")[0];
}
set { ExtensionSet("ExtensionAttributeName", value); }
}
public static new UserPrincipalEx FindByIdentity
(PrincipalContext context, string identityValue)
{
return (UserPrincipalEx)FindByIdentityWithType
(context, typeof(UserPrincipalEx), identityValue);
}
public static new UserPrincipalEx FindByIdentity
(PrincipalContext context, IdentityType identityType, string identityValue)
{
return (UserPrincipalEx)FindByIdentityWithType
(context, typeof(UserPrincipalEx), identityType, identityValue);
}
}
}
Now, you can use the "extended" version of the <font face="Courier New">UserPrincipalEx</font>
in your code:
public UserPrincipalEx GetUserEx(string sUserName)
{
PrincipalContext oPrincipalContext = GetPrincipalContext();
UserPrincipalEx oUserPrincipal = UserPrincipalEx.FindByIdentity(oPrincipalContext, sUserName);
return oUserPrincipal;
}
Here is how to use the code:
public static PersonInfo GetUserInfoFromAD(String UserName)
{
PersonInfo empInfo;
try
{
ADMethodsAccountManagement accountManagement = new ADMethodsAccountManagement();
UserPrincipalEx user = accountManagement.GetUserEx(UserName);
empInfo = new PersonInfo()
{
UserName = user.Name,
Name = user.DisplayName,
Email = user.EmailAddress,
PhotoUrl = user.ExtensionAttributeName
};
}
catch (Exception ex)
{
empInfo = null;
Helper.Logging.LogError(ex.Message, ex);
throw;
}
return empInfo;
}