I’d been wanting to build an export and import command for Audiences for quite some time but just haven’t gotten around to it. I’m currently looking for a good sample command to build during a possible talk at the next Best Practices conference so I decided to give this one a whack considering that I already had a good chunk of the code written and just needed to repurpose it. I don’t know if I’ll use this command for the presentation so if anyone has any good ideas of things they’d like to see please let me know and I’ll look into it.

One of the things I was hoping to achieve through this was the ability to do an import and preserve the ID of the Audience so that content targeting Audiences could be migrated between environments – unfortunately I quickly discovered that the ID is set via stored procedures during the creation of the Audience so there was no way for me to intercept the creation process and change the ID without going to the database directly which is something I was not willing to do. I decided that the ability to migrate Audiences between environments, even without being able to set the ID, was still valuable so I went ahead with the creation of the commands.

To do the export I get an instance of the AudienceManager class and then loop through the collection of Audience objects using the Audiences property. I then use an XmlTextWriter to write out all the properties of the Audience and then I loop through the AudienceRuleComponent objects which you can get via the AudienceRules property of the Audience object, once again writing out all the properties using the XmlTextWriter. There’s really not much to it as you can see in the code below:

  1#if MOSS
  2using System;
  3using System.Collections;
  4using System.Collections.Specialized;
  5using System.IO;
  6using System.Text;
  7using System.Xml;
  8using Lapointe.SharePoint.STSADM.Commands.OperationHelpers;
  9using Lapointe.SharePoint.STSADM.Commands.SPValidators;
 10using Microsoft.Office.Server;
 11using Microsoft.Office.Server.Audience;
 12using Microsoft.SharePoint;
 13 
 14namespace Lapointe.SharePoint.STSADM.Commands.Audiences
 15{
 16    public class ExportAudiences : SPOperation
 17    {
 18        /// <summary>
 19        /// Initializes a new instance of the <see cref="ExportAudiences"/> class.
 20        /// </summary>
 21        public ExportAudiences()
 22        {
 23            SPParamCollection parameters = new SPParamCollection();
 24            parameters.Add(new SPParam("name", "n", false, null, new SPNonEmptyValidator()));
 25            parameters.Add(new SPParam("ssp", "ssp", false, null, new SPNonEmptyValidator()));
 26            parameters.Add(new SPParam("explicit", "ex"));
 27            parameters.Add(new SPParam("outputfile", "output", false, null, new SPDirectoryExistsAndValidFileNameValidator()));
 28 
 29            StringBuilder sb = new StringBuilder();
 30            sb.Append("\r\n\r\nExports all audiences or a specific audience if a name is provided.\r\n\r\nParameters:");
 31            sb.Append("\r\n\t-outputfile <file to output results to>");
 32            sb.Append("\r\n\t[-name <audience name>]");
 33            sb.Append("\r\n\t[-ssp <SSP name>]");
 34            sb.Append("\r\n\t[-explicit (shows field and value attributes for every rule)]");
 35            Init(parameters, sb.ToString());
 36        }
 37 
 38        /// <summary>
 39        /// Gets the help message.
 40        /// </summary>
 41        /// <param name="command">The command.</param>
 42        /// <returns></returns>
 43        public override string GetHelpMessage(string command)
 44        {
 45            return HelpMessage;
 46        }
 47 
 48        /// <summary>
 49        /// Executes the specified command.
 50        /// </summary>
 51        /// <param name="command">The command.</param>
 52        /// <param name="keyValues">The key values.</param>
 53        /// <param name="output">The output.</param>
 54        /// <returns></returns>
 55        public override int Execute(string command, StringDictionary keyValues, out string output)
 56        {
 57            output = string.Empty;
 58 
 59            string outputFile = Params["outputfile"].Value;
 60            string xml = Export(Params["ssp"].Value, Params["name"].Value, Params["explicit"].UserTypedIn);
 61 
 62            File.WriteAllText(outputFile, xml);
 63 
 64            return OUTPUT_SUCCESS;
 65        }
 66 
 67        /// <summary>
 68        /// Returns an XML structure containing all the audience details.
 69        /// </summary>
 70        /// <param name="sspName">Name of the SSP.</param>
 71        /// <param name="audienceName">Name of the audience.</param>
 72        /// <param name="includeAllAttributes">if set to <c>true</c> [include all attributes].</param>
 73        /// <returns></returns>
 74        private string Export(string sspName, string audienceName, bool includeAllAttributes)
 75        {
 76            ServerContext context;
 77            if (string.IsNullOrEmpty(sspName))
 78                context = ServerContext.Default;
 79            else
 80                context = ServerContext.GetContext(sspName);
 81 
 82            AudienceManager manager = new AudienceManager(context);
 83 
 84            if (!string.IsNullOrEmpty(audienceName) && !manager.Audiences.AudienceExist(audienceName))
 85            {
 86                throw new SPException("Audience name does not exist");
 87            }
 88 
 89            StringBuilder sb = new StringBuilder();
 90            XmlTextWriter xmlWriter = new XmlTextWriter(new StringWriter(sb));
 91            xmlWriter.Formatting = Formatting.Indented;
 92 
 93            xmlWriter.WriteStartElement("Audiences");
 94 
 95            if (!string.IsNullOrEmpty(audienceName))
 96            {
 97                Audience audience = manager.Audiences[audienceName];
 98                ExportAudience(xmlWriter, audience, includeAllAttributes);
 99            }
100            else
101            {
102                foreach (Audience audience in manager.Audiences)
103                    ExportAudience(xmlWriter, audience, includeAllAttributes);
104            }
105 
106            xmlWriter.WriteEndElement(); // Audiences
107            xmlWriter.Flush();
108            return sb.ToString();
109        }
110 
111        /// <summary>
112        /// Exports the audience.
113        /// </summary>
114        /// <param name="xmlWriter">The XML writer.</param>
115        /// <param name="audience">The audience.</param>
116        /// <param name="includeAllAttributes">if set to <c>true</c> [include all attributes].</param>
117        private static void ExportAudience(XmlWriter xmlWriter, Audience audience, bool includeAllAttributes)
118        {
119            xmlWriter.WriteStartElement("Audience");
120            xmlWriter.WriteAttributeString("AudienceDescription", audience.AudienceDescription);
121            xmlWriter.WriteAttributeString("AudienceID", audience.AudienceID.ToString());
122            xmlWriter.WriteAttributeString("AudienceName", audience.AudienceName);
123            xmlWriter.WriteAttributeString("AudienceSite", audience.AudienceSite);
124            xmlWriter.WriteAttributeString("CreateTime", audience.CreateTime.ToString());
125            xmlWriter.WriteAttributeString("GroupOperation", audience.GroupOperation.ToString());
126            xmlWriter.WriteAttributeString("LastCompilation", audience.LastCompilation.ToString());
127            xmlWriter.WriteAttributeString("LastError", audience.LastError);
128            xmlWriter.WriteAttributeString("LastPropertyUpdate", audience.LastPropertyUpdate.ToString());
129            xmlWriter.WriteAttributeString("LastRuleUpdate", audience.LastRuleUpdate.ToString());
130            xmlWriter.WriteAttributeString("MemberShipCount", audience.MemberShipCount.ToString());
131            xmlWriter.WriteAttributeString("OwnerAccountName", audience.OwnerAccountName);
132 
133 
134            ArrayList audienceRules = audience.AudienceRules;
135            xmlWriter.WriteStartElement("rules");
136            if (audienceRules != null && audienceRules.Count > 0)
137            {
138                foreach (AudienceRuleComponent rule in audienceRules)
139                {
140                    xmlWriter.WriteStartElement("rule");
141                    if (includeAllAttributes)
142                    {
143                        xmlWriter.WriteAttributeString("field", rule.LeftContent);
144                        xmlWriter.WriteAttributeString("op", rule.Operator);
145                        xmlWriter.WriteAttributeString("value", rule.RightContent);
146                    }
147                    else
148                    {
149                        switch (rule.Operator.ToLowerInvariant())
150                        {
151                            case "=":
152                            case ">":
153                            case ">=":
154                            case "<":
155                            case "<=":
156                            case "contains":
157                            case "<>":
158                            case "not contains":
159                                xmlWriter.WriteAttributeString("field", rule.LeftContent);
160                                xmlWriter.WriteAttributeString("op", rule.Operator);
161                                xmlWriter.WriteAttributeString("value", rule.RightContent);
162                                break;
163                            case "reports under":
164                            case "member of":
165                                xmlWriter.WriteAttributeString("op", rule.Operator);
166                                xmlWriter.WriteAttributeString("value", rule.RightContent);
167                                break;
168                            case "and":
169                            case "or":
170                            case "(":
171                            case ")":
172                                xmlWriter.WriteAttributeString("op", rule.Operator);
173                                break;
174                        }
175                    }
176                    xmlWriter.WriteEndElement(); // rule
177                }
178            }
179            xmlWriter.WriteEndElement(); // rules
180            xmlWriter.WriteEndElement(); // Audience
181        }
182    }
183}
184#endif

The help for the command is shown below:

C:\>stsadm -help gl-exportaudiences

stsadm -o gl-exportaudiences

Exports all audiences or a specific audience if a name is provided.

Parameters:
        -outputfile <file to output results to>
        [-name <audience name>]
        [-ssp <SSP name>]
        [-explicit (shows field and value attributes for every rule)]

The following table summarizes the command and its various parameters:

Command NameAvailabilityBuild Date
gl-exportaudiencesMOSS 2007Released: 4/17/2009
Parameter NameShort FormRequiredDescriptionExample Usage
outputfileoutputYesThe path to the output file to save the exported audience details.-outputfile c:\audiences.xml, -output c:\audiences.xml
namenNoThe name of a specific audience if only one audience is to be exported.-name HR, -n HR
sspNoThe name of the SSP containing the audiences to export. If omitted then the default SSP will be used.-ssp SSP1
explicitexNoIf specified then all field and value properties for the rules will be populated (in many cases these properties are redundant and do not add any information and are not necessary for import).-explicit

The following is an example of how to export all audiences belonging to SSP1:

stsadm -o gl-exportaudiences -outputfile c:\audiences.xml -ssp SSP1

The following shows an example output of running the above command:

 1<Audiences>
 2  <Audience AudienceDescription="All users who can access the site" AudienceID="00000000-0000-0000-0000-000000000000" AudienceName="All site users" AudienceSite="http://sspadmin/ssp/admin" CreateTime="1/1/0001 12:00:00 AM" GroupOperation="AUDIENCE_NOGROUP_OPERATION" LastCompilation="1/1/0001 12:00:00 AM" LastError="" LastPropertyUpdate="1/1/0001 12:00:00 AM" LastRuleUpdate="1/1/0001 12:00:00 AM" MemberShipCount="0" OwnerAccountName="">
 3    <rules />
 4  </Audience>
 5  <Audience AudienceDescription="" AudienceID="a2e62d72-fa52-4772-a5d0-9b950ec7d220" AudienceName="HR" AudienceSite="http://sspadmin/ssp/admin" CreateTime="4/20/2009 8:23:48 PM" GroupOperation="AUDIENCE_OR_OPERATION" LastCompilation="4/20/2009 8:26:22 PM" LastError="" LastPropertyUpdate="4/20/2009 8:26:07 PM" LastRuleUpdate="4/20/2009 8:26:07 PM" MemberShipCount="6" OwnerAccountName="spdev\spadmin">
 6    <rules>
 7      <rule op="Member of" value="CN=Human Resources Dept,OU=Users,DC=CompanyName,DC=com" />
 8      <rule op="OR" />
 9      <rule field="Department" op="=" value="Human Resources" />
10    </rules>
11  </Audience>
12</Audiences>