Programmatically Targeting Audiences for Audience Enabled Libraries in SharePoint

Overview

Targeting an audience for a given document is a great capability within SharePoint. There’s a simple Document Library setting to enable Audience Targetting.

This enables a dedicated Audience Targeting field to be configured per document. I customized a Content Query Web Part (CQWP) that honors audience targeting, while displaying the fields in a grid view, enabling a targeted and custom portal home page. While the CQWP is harder to work with than a Data View Web Part, CQWP is the primary way to leverage Audience targetting.

Reporting

I prefer to first output a CSV of all documents, with one column for Audience. Note I also output the absolute URL. Here’s a function to do it. Note the proper use of memory management:

$LineHeader= 'Site,Lib,URL,ID,Versions,Name,Title,Created,Modified By,Modified,Audiences'
$LineHeader | Out-file -Filepath $ReportFile
function generate-VerReport ($WebUrl, $ListName)
{
$ac=Start-SPAssignment
$web = $ac | Get-SPWeb $WebUrl
$list = $web.Lists[$ListName]
$VerOut=$null;
Write-Host "+" -NoNewline #each plus is a full look through all Docs in a library
$xSit=$WebUrl;
$xLis=$ListName;
#Go through each item in the list
$Items = $list.Items
$ItemCount = $Items.count;
for ($i=0; $i -lt $ItemCount; $i++)
{
#Check if the item content type currently equals the old content type specified
$item=$items[$i];
$sep='","';
$xURL = $Item["EncodedAbsUrl"]
$RawAud = $item["Target Audiences"];
$xNam=$item['Name']
$xTit=$item['Title']
$xCre=$item['Created']
$xEdi=$item["Editor"]
$xMod=$item["Modified"]
$xID= $item.ID
$xVer= $item.Versions.count;
$Line1='"'+$xSit+$sep+$xLib+$sep+$xURL+$sep+$xID+$sep+$xVer+$sep+$xNam+$sep+$xTit+$sep+$xCre+$sep+$xEdi+$sep+$xMod+$sep+$rawAud,'"';
$Line1 | Out-file -Filepath $ReportFile -Append
#$LineHeader+= '`r`n'
#$VerOut+=$Line1;
}
$LineHeader+= '`r`n'
$LineHeader | Out-file -Filepath $ReportFile -Append
$web.Dispose()
$ac | Stop-SPAssignment
}

Here’s the function call:

generate-VerReport -weburl $web.url -listname $JPlib

The output enables an end user to modify the CSV to specify the audience per document.

Audience Shuffling

I created a script to apply the Audiences specified per document in the control spreadsheet. The Audiences are expected to be in semi-colon separated format (multiple values possible). There is no error checking on spelling of Audiences. It turns out Document Audiences in SharePoint are weakly-typed. That is to say, it is simply a string. The string has four semi-colons. In this script, we only apply SharePoint Groups, and they appear as comma separated after four semi-colons. If multiple values appear, these are comma separated. If an AD group is used, then that appears nestled between two pairs of semi-colons, as in this example:
;;CN=GroupName Membership,OU=Security Groups,OU=Information Technology,DC=MyDomain,DC=com;;
Under the covers, SharePoint will accept not just AD groups and SharePoint groups, but also UPS (User Profile Service) Audiences, specified as GUIDs. So two semi-colons are used as delimiters (beats me, but this is the first time I’ve seen this convention). Here’s how it is structured:
[Guids, comma separated];;[AD group LDAP paths separated by line breaks];;[SharePoint security group names, comma separated]

Here’s the script to apply the Audiences. It assumes all are SharePoint Groups, but is easily extensible to support AD groups if desired. Note it does not do checking for validity of SharePoint groups. Note the “Action” column to determine whether to “D”elete or “A”ssign audiences:

Add-PSSnapin "Microsoft.SharePoint.PowerShell" -ErrorAction SilentlyContinue
Start-SPAssignment –Global
$ShuffleSource = "C:UsersplautjDocumentsPowerShellAudienceShuffle.txt"
$siteUrl = "ht tp://sharepoint"
Write-Host "script starting $(get-date)"
$myheader = "STARTING: $(get-date)"
$ShuffArr = Import-Csv -Path $ShuffleSource -Delimiter "`t"
$ShuffCount = $ShuffArr.count;
for ($i=0; $i -lt $ShuffCount; $i++)
{
$Row = $ShuffArr[$i]
if (($Row.action -ne $null) -and ($Row.action.length -ne 0))
{
$docurl = $row.url;
$site = New-Object Microsoft.SharePoint.SPSite($docurl)
$web = $site.OpenWeb()
$item = $web.GetListItem($docurl)
$list = $item.ParentList
if ($Row.action -eq "D")
{
$item["Target Audiences"] = $null;
$item.SystemUpdate();
}
elseif ($Row.action -eq "A")
{
if ($Row.Audiences -gt 0) #ignore if empty
#actual Target Audience property has four semicolons, followed by comma delimited sharepoint groups
#for AD group is how semicolons work ;;CN=ADW Membership,OU=Security Groups,OU=Information Technology,DC=DOMAIN,DC=com;;
{
$AudBuilder = ";;;;"
$AudArr = $Row.Audiences.Split(";");
for ($ai=0; $ai-lt $AudArr.Count; $ai++)
{
if ($ai-gt 0)
{
$AudBuilder = $AudBuilder + ","
}
$AudBuilder = $AudBuilder + $AudArr[$ai]
}
$item["Target Audiences"] = $AudBuilder;
$item.SystemUpdate();
} #IF Audiences is not null
} #Add action
} #action exists
} #loop of rows
Write-Host "script finishing $(get-date)"
Stop-SPAssignment –Global
###########################
0 replies

Leave a Reply

Want to join the discussion?
Feel free to contribute!

Leave a Reply

Your email address will not be published. Required fields are marked *