SharePoint Portal audience compilation testing code sample
Today is fun with Audiences day! Audience compilation is a codebase that I am very familiar with. John West (blogs.msdn.com/johnwe/) recently posted that if you're having audience compilation issues to make sure you had the latest Portal rollup applied. I'll echo that statement here and note that in reality you simply have to have Microsoft.SharePoint.Portal.dll beyond build 11.0.6715.13 (support.microsoft.com/?id=887819) then you will have the fixes he is speaking of.
Now assuming we're past that, Audience compilation itself has many codepaths that it can go down. The one that seems to cause most folks pain is audiences utilizing the member of ruleset. Other audience issues are typically caused by an out-of-date or incomplete profile import as they source the _PROF database for their information. Member of is unique because it goes out to AD at compile-time and that is where we can run into problems. If you dont have permissions to AD, AD is inaccessible, there are name resolution problems, network problems, etc--then member of compiles could experience problems/incompleteness.
In these circumstances you may want to get a look at SharePoint's view of a security group you are trying to use with member of without actually doing a compile. For instance, if you know there are failures you might manually run the compile until you get a successful one. You may not want to then destroy your compiled audience, but you still want to troubleshoot. This kind of code can help in that situation. It also of course lets me show you some Audience code. :-)
Today's sample will require:
using Microsoft.SharePoint.Portal.Audience;
Refer to blogs.msdn.com/dwinter/archive/2005/03/01/383306.aspx (Portal OM) and blogs.msdn.com/dwinter/archive/2005/02/15/373076.aspx (WSS OM) for setup if you are not familiar with creating a SharePoint OM application.
We'll start with a C# Windows Form application. I am using Microsoft.SharePoint, Microsoft.SharePoint.Portal, System.Web, Microsoft.SharePoint.Portal.Audience, and Microsoft.SharePoint.Portal.Topology in these samples. Use the same kind of setup in your designer that I showed in the initial Portal OM post.
Here's the code sample:
private
void button1_Click(object sender, System.EventArgs e)
{
ArrayList myADsMemberShip=null;
ArrayList myADsPath=null;
listBox2.Items.Clear();
TopologyManager myTopologyManager = new TopologyManager();
PortalSite myPortalSite = myTopologyManager.PortalSites[new Uri(textBox1.Text)];
PortalContext myPortalContext = PortalApplication.GetContext(myPortalSite);
AudienceManager myAudienceManager = new AudienceManager(myPortalContext);
if (myAudienceManager != null)
{
foreach (Audience myAudience in myAudienceManager.Audiences)
{
try
{
listBox2.Items.Add(myAudience.AudienceName+" count: "+myAudience.MemberShipCount.ToString());
foreach (AudienceRuleComponent myRules in myAudience.AudienceRules)
{
//m_RightContent will be DOMAIN\GROUPNAME
myADsPath = myAudienceManager.GetADsPath(myRules.m_RightContent);
//myADsPath[0] will be the DN that the groupname resolved to
//GetADsPath itself could be used to test AD connectivity
listBox2.Items.Add("Processing: "+myADsPath[0].ToString());
try
{
myADsMemberShip = AudienceManager.GetADMemberShip((string)myADsPath[0]);
}
catch (Exception ex)
{
listBox2.Items.Add(ex.Message);
}
}
if (myADsMemberShip.Count > 0)
{
listBox2.Items.Add(myAudience.AudienceName+" AD results");
}
foreach (MembershipInfo myAudienceMember in myADsMemberShip)
{
listBox2.Items.Add(myAudienceMember.cn);
}
}
catch (System.NullReferenceException)
{
listBox2.Items.Add("Nothing to do");
}
catch (Exception ex)
{
listBox2.Items.Add(ex.Message);
}
}
}
}
So this should list all your audiences, tell you the DN it is working on and show you the CNs of the users that it just pulled from AD while processing that audience. The beauty of this is that it doesn't actually update the audience or change the audience at all.
If your purpose is to compile a single audience, just call audiencejob.exe from cmd line and pass the same parameters the scheduled task vbs is using, and add the audience name as an additional parameter on the end. Note that the 180 parameter is the number of minutes the compile will run, so if your audiences take a long time to compile you may need to increase this.