Prexens team dev' corner

Retrieve profile information from members of an audience field

Goal of this post
 
By enabling audience targeting option on a list or library, you can display content only to people who are members of a particular group or audience.
 
Enable audience targeting
You can then specify audience members through Audience Targeting field.
Audience targeting field

But how to retrieve all members from this audience field programmatically? For instance, how to get their email addresses?
 

What an audience is composed of?
 
Target audience field can only contain 3 types of objects (see screenshot below):
  1. Global audiences (can be defined in the Shared Services Administration of the SharePoint central administration, Audiences section).
  2. Distribution/Security Groups (groups of your Active Directory).
  3. SharePoint Groups.

Audience selection


Let's code

1. Audience property

Once you filled-in target audience field , data are stored in "Audience" property of the underlying element (e.g. item, document, navigation node).

string audiencePropertyString = Convert.ToString(item.Properties["Audience"]);
Note that we use Convert.ToString() instead of .ToString() to avoid any null exception if the property does not exist.


2. Get audience IDs from audience property

AudienceManager class provides a very handy method GetAudienceIDsFromText that retrieves member's identifiers.
string[] globalAudienceIds;
string[] dlDistinguishedNames;
string[] sharePointGroupNames;

int result = AudienceManager.GetAudienceIDsFromText(
    audiencePropertyString,
    out globalAudienceIds,
    out dlDistinguishedNames,
    out sharePointGroupNames);

We now have three arrays fulfilled with audiences IDs.


3. Get users from global audiences

Once compiled, a global audience is just a list of users. Thus it's quite straightforward to enumerate them.

foreach (string globalAudienceId in globalAudienceIds)
{
    AudienceManager am = new AudienceManager(ServerContext.GetContext(SPContext.Current.Site));

    foreach (UserInfo member in am.GetAudience(new Guid(globalAudienceId)).GetMembership())
    {
        string email = member.Email;
        // TODO: what you need with this email ...
    }
}


4. Get emails of security groups members


In this example, we won't try to get users that are in groups of groups.

First this simple method helps us to get members of an Active Directory group:

/// <summary>
/// Get members of a specified AD group
/// </summary>
/// <param name="groupName">AD group name</param>
/// <returns>Members</returns>
private static List<DirectoryEntry> GetWindowsGroupMembers(string groupName)
{
    // Variables
    List<DirectoryEntry> members;
    DirectorySearcher ds;
    ResultPropertyCollection results;
    DirectoryEntry member;

    // Init
    members = new List<DirectoryEntry>();
    ds = new DirectorySearcher();

    // Init directory searcher filter
    if (groupName.StartsWith("cn=", StringComparison.InvariantCultureIgnoreCase))
    {
        ds.Filter = String.Format("({0})", groupName);
    }
    else
    {
        ds.Filter = String.Format("(cn={0})", groupName);
    
    }

    // Execute search
    results = ds.FindOne().Properties;

    // Get group members    foreach (Object memberColl in results["member"])
    {
        member = new DirectoryEntry(String.Format("LDAP://{0}", memberColl));

        if (member != null)
        {
            members.Add(member);
        }
    }

    // Return members list
    return members;
}


Then this method helps to get a property value of an active directory entry:

/// <summary>
/// Get property value from AD entry
/// </summary>
/// <param name="entry">Directory entry to request</param>
/// <param name="propertyName">Property name</param>
/// <returns>Property value</returns>
private static object GetWindowsUserPropertyValue(DirectoryEntry entry, string propertyName)
{
    // Variables
    object propertyValue = null;
    System.DirectoryServices.PropertyCollection userProps = null;

    // Get AD entry properties
    userProps = entry.Properties;
            
    // Get specified property values
    propertyValue = userProps[propertyName].Value;

    // Return property value
    return propertyValue;
}


Finally we get email adresses from security groups members:

foreach (string dlDistinguishedName in dlDistinguishedNames)
{
    // Connect to AD group
    DirectoryEntry group = new DirectoryEntry(String.Format("LDAP://{0}", dlDistinguishedName));
                
    // Init directory searcher
    DirectorySearcher ds = new DirectorySearcher(group);
                
    // Get AD group name
    string groupName = ds.FindOne().GetDirectoryEntry().Name;
    if (groupName.Contains(@"\"))
    {
        groupName = groupName.Substring(groupName.LastIndexOf(@"\") + 1);
    }

    // Get users infos
    foreach (DirectoryEntry member in GetWindowsGroupMembers(groupName))
    {
        string email = Convert.ToString(GetWindowsUserPropertyValue(member, "mail"));
        // TODO: what you need with this email ...
    }
}



5. Get users from SharePoint groups

A SharePoint group is composed of SharePoint users, but a SharePoint user can also be a security group!

foreach (string sharePointGroupName in sharePointGroupNames)
{
    // Get users from group
    foreach (SPUser user in SPContext.Current.Web.SiteGroups[sharePointGroupName].Users)
    {
        // Add simples users emails to list
        if (!user.IsDomainGroup)
        {
            string email = user.Email;
            // TODO: what you need with this email ...
        }
        // The user is an AD group reference
        else
        {
            // Get AD group names
            string groupName = null;
            if (user.LoginName.Contains(@"\"))
            {
                groupName = user.LoginName.Substring(user.LoginName.LastIndexOf(@"\") + 1);
            }
            else
            {
                groupName = user.LoginName;
            }

            // Get users infos and add email to list
            foreach (DirectoryEntry member in GetWindowsGroupMembers(groupName))
            {
                string email = Convert.ToString(GetWindowsUserPropertyValue(member, "mail"));
                // TODO: what you need with this email ...
            }
        }
    }
}


Important note

To be able to browse your Active Directory, the application pool identity must be a domain account. But this should be the case...


Comments

No comments yet for this post.

Add a new comment

Please  [ Sign in ] to add a new comment
Categories
Links
  Prexens Web Site
  Charting for SharePoint
  Charting for SharePoint (Codeplex)
  Charting for SharePoint Starter kit

Microsoft Certified Partner