The project that I’m currently working has a need to create a ton of audiences representing divisions, departments, locations, etc. We wanted to be able to include the creation of these audiences in our install script so that we easily recreate the audiences in various environments.

To accomplish this task there were two core things I had to figure out – the first was how to create the actual audience, this was the easy part. The second was how to assign rules to that audience – I’ll discuss this problem in my next post.

Creating an audience programmatically turned out to be real easy – you basically just get an instance of the AudienceManager class by passing in an SSP context into the constructor and then you use the Audiences property (which is of type AudienceCollection) and call the Create method to create the audience. The Create method returns back an Audience object which you can then use to set additional properties such as the owner (OwnerAccountName) and the group operation (GroupOperation). You then call Commit to save the changes.

The GroupOperation property probably needs some additional explanation. The value it takes is an AudienceGroupOperation enum which consists of the following values:

  1. AUDIENCE_AND_OPERATION
  2. AUDIENCE_OR_OPERATION
  3. AUDIENCE_MIX_OPERATION
  4. AUDIENCE_NOGROUP_OPERATION

This property defines how the audience rules are handled. If you specify AUDIENCE_AND_OPERATION then every rule specified will have to result in a match for an item to be returned. If you specify AUDIENCE_OR_OPERATION then if any of the rules matched for an item then it will be returned. This is consistent with the behavior you get when creating rules via the browser. If you set the value to AUDIENCE_NOGROUP_OPERATION then you are saying there is no grouping, or more specifically there will be only one rule.

Here’s the one that may surprise some people (it did me) – the AUDIENCE_MIX_OPERATION basically says that I want to create a complex grouping of rules – so something like ‘(Department == "IT" and Reports Under "John Smith") or Hero == true. That’s great right? You can build audiences with complex rules so you can finally get creative – here’s the catch: once you do this you can no longer manage those rules via the browser – the only thing you’ll be able to do is compile the rule and view memberships – you won’t even be able to delete it. But don’t worry – I’ve got you covered – stay tuned for future posts! One more thing – you can’t set the GroupOperation property to AUDIENCE_MIX_OPERATION – this value will be returned if your rules are complex but you can’t preset the value. I found the best thing to do is to just not set this property at all – but I did choose to expose it in the command I created which I called gl-createaudience.

Here’s a snip of the core code that you need to create the actual audience (again, adding rules will be covered in my next post):

 1public static void Create(string sspName, string audienceName, string description, RuleEnum rule, string owner)
 2{
 3    ServerContext context;
 4    if (string.IsNullOrEmpty(sspName))
 5        context = ServerContext.Default;
 6    else
 7        context = ServerContext.GetContext(sspName);
 8 
 9    AudienceManager manager = new AudienceManager(context);
10    AudienceCollection auds = manager.Audiences;
11 
12    if (auds.AudienceExist(audienceName))
13    {
14        throw new SPException("Audience name already exists");
15    }
16    Audience audience = auds.Create(audienceName, description??"");// IMPORTANT: the create method does not do a null check but the methods that load the resultant collection assume not null.
17    if (rule == RuleEnum.Any)
18        audience.GroupOperation = AudienceGroupOperation.AUDIENCE_OR_OPERATION;
19    else if (rule == RuleEnum.All)
20        audience.GroupOperation = AudienceGroupOperation.AUDIENCE_AND_OPERATION;
21 
22    if (!string.IsNullOrEmpty(owner))
23    {
24        audience.OwnerAccountName = owner;
25    }
26    else
27    {
28        audience.OwnerAccountName = string.Empty;
29    }
30    audience.Commit();
31}

The help for the command is shown below:

C:\>stsadm -help gl-createaudience

stsadm -o gl-createaudience


Creates an audience.

Parameters:
        -name <audience name>
        [-ssp <SSP name>]
        [-description <audience description>]
        [-owner <DOMAIN\user>]
        [-rule <any | all | mix> (default is any)]
        [-update (if the audience exists, update it)]

The following table summarizes the command and its various parameters:

Command NameAvailabilityBuild Date
gl-createaudienceMOSS 2007Released: 8/6/2008, Updated: 8/14/2008
Parameter NameShort FormRequiredDescriptionExample Usage
namenYesThis is the name of the audience.-name "IT Department", -n "IT Department"
sspNoThe name of the SSP to create the audience within. If not specified then the default SSP is used.-ssp SSP1
descriptiondescNoA brief description of the audience. I like to provide a text version of the rules that are applied. This makes it easier to manage via the browser especially when complex rules are used.-description "All employees who are members of the IT Department: Department==IT or Reports Under==John Smith", -desc "All employees who are members of the IT Department: Department==IT or Reports Under==John Smith"
ownerNoThe login name of the user who will be assigned as the owner of the audience. Though not required it’s always recommended to identify someone as the person who is responsible for the logic behind the rules.-owner "domain\user1"
rulerNoOne of the following values: Any, All, Mix. If Mix is specified it behaves the same as though the parameter were omitted.-rule Any, -r Any
updateuNoIf specified then the existing audience, if found, will be updated. This is useful when using the command in the context of a script that you’d like to be able to run repeatedly without having to delete the audience and therefore have to reset any items using that audience.-update, -u

The following is an example of how to create an audience named “IT Department”:

stsadm -o gl-createaudience -name "IT Department" -description "All employees of who are members of the IT Department: (Department==IT or Reports Under==John Smith) and IsContractor==false" -rule mix -owner domain\user1

Update 8/14/2008: I’ve added an -update parameter to allow updating the audience if it already exists.