In order to access all active directory properties, you could use System.DirectoryServices framework (CLR) like Microsoft in its user import wizard (SysUserADUserImportWizard form).
In this form, you could observe this kind of managed code used in element.searchADUser() method (AX 2009 for instance).
I created a little class to retrieve some user with a domain and sid, and another one to retrieve userInfo record from an UPN (UserPrincipalName) parsing all domain of AD (because active directory could be composed with many domain names).
Here is the sample to retrieve a UPN from a SID and domain :
static EMail getUPNFromUserInfo(SID _sid,NetworkDomain _domain)
{
System.DirectoryServices.DirectorySearcher directorySearcher;
System.DirectoryServices.SearchResult searchResult;
System.DirectoryServices.DirectoryEntry entry;
System.DirectoryServices.PropertyCollection PropertyCollection;
System.DirectoryServices.PropertyValueCollection PropertyValueCollection;
System.DirectoryServices.SearchScope searchScope;
str selectedDomainName = _domain;
str prefix = 'LDAP://';
int totalNumber;
int i;
str criteria;
str adUPN = '';
;
if(_sid && _domain)
{
try
{
searchScope = CLRInterop::parseClrEnum('System.DirectoryServices.SearchScope', 'Subtree');
entry = new System.DirectoryServices.DirectoryEntry(prefix+selectedDomainName);
directorySearcher = new System.DirectoryServices.DirectorySearcher(entry);
directorySearcher.set_PageSize(65535);
directorySearcher.set_CacheResults(false);
directorySearcher.set_SearchScope(searchScope);
criteria += strfmt('(objectSid=%1)', _sid) ;
directorySearcher.set_Filter(strfmt('(&(objectClass=user)(objectCategory=person)%1(userAccountControl:1.2.840.113556.1.4.803:=512))', criteria));
searchResult = directorySearcher.FindOne();
if(searchResult)
{
entry = searchResult.GetDirectoryEntry();
if (entry)
{
PropertyCollection = entry.get_Properties();
}
if (!PropertyCollection)
{
continue;
}
PropertyValueCollection = PropertyCollection.get_Item('userPrincipalName');
if (PropertyValueCollection)
{
if (PropertyValueCollection.get_Value())
{
adUPN = PropertyValueCollection.get_Value();
//newAlias = PropertyValueCollection.get_Value();
}
}
}
}
catch (Exception::CLRError)
{
error("@SYS117735");
return '';
}
}
return adUPN;
}
The other algorithm to find a user from UserPrincipalName in AX :
Domain isn't in parameters of the method, so we need to check all domain available.
static UserInfo getUserInfoFromADUPN(EMail _upn)
{
System.DirectoryServices.DirectorySearcher directorySearcher;
System.DirectoryServices.SearchResult searchResult;
System.DirectoryServices.DirectoryEntry entry;
System.DirectoryServices.PropertyCollection PropertyCollection;
System.DirectoryServices.PropertyValueCollection PropertyValueCollection;
System.DirectoryServices.SearchScope searchScope;
str selectedDomainName;
str prefix = 'LDAP://';
int totalNumber;
str criteria;
str networkDomain,domainNameTmp;
NetworkAlias adAlias;
AxaptaUserManager mgr;
container domainNames;
int domainCount,j,totalfound;
UserInfo userInfo;
;
if(_upn)
{
try
{
mgr = new AxaptaUSerManager();
domainNames = mgr.enumerateDomains('');
if(domainNames)
{
domainCount = conlen(domainNames);
// Add all the domain names to the domains combo box
if(domainCount > 0)
{
for(j=0;j<domainCount;j++)
{
domainNameTmp = '';
domainNameTmp = conpeek(domainNames, j+1);
searchScope = CLRInterop::parseClrEnum('System.DirectoryServices.SearchScope', 'Subtree');
entry = new System.DirectoryServices.DirectoryEntry(prefix+domainNameTmp);
directorySearcher = new System.DirectoryServices.DirectorySearcher(entry);
directorySearcher.set_PageSize(65535);
directorySearcher.set_CacheResults(false);
directorySearcher.set_SearchScope(searchScope);
criteria += strfmt('(userPrincipalName=%1)', _upn) ;
directorySearcher.set_Filter(strfmt('(&(objectClass=user)(objectCategory=person)%1(userAccountControl:1.2.840.113556.1.4.803:=512))', criteria));
searchResult = directorySearcher.FindOne();
if(searchResult)
{
//searchResult = searchResultCollection.get_Item(0);
entry = searchResult.GetDirectoryEntry();
if (entry)
{
PropertyCollection = entry.get_Properties();
}
if (!PropertyCollection)
{
continue;
}
PropertyValueCollection = PropertyCollection.get_Item('samAccountName');
if (PropertyValueCollection)
{
if (PropertyValueCollection.get_Value())
{
adAlias = PropertyValueCollection.get_Value();
break;
}
}
}
}
}
}
}
catch (Exception::CLRError)
{
error("@SYS117735");
return null;
}
}
userInfo.clear();
if(adAlias)
{
select userInfo where userInfo.id == adAlias;
}
return userInfo;
}
In order to use other Active Directory properties, you can use ADExplorer to check name of properties and use it in PropertyCollection class (get_item() method)
Hope this could be helpful.
J.