Monday, July 27, 2015

Apply a Retention Policy to a Set of Content Types Via PowerShell

Hello Readers!

Recently it seems that I have been doing more and more PowerShell, this time I needed to apply a retention policy to a set of Content Types.  In order to do this I wrote a PowerShell script which checks all of the content types within your site against a list of content types stored in an array.  If the content type name matches the name within the array we apply the policy.  My policy is extremely simple and simply marks the item as a record when today is equal to my field ExpirationDate.

Many users will need a policy much more robust than this and my advice is to download SharePoint 2013 manager in order to create them https://spm.codeplex.com/.  With SharePoint Manager 2013 you can open an existing policy that you have made via the GUI and extract the XML.  The script needs the XML markup in order to create the policy and writing it by hand is horrible!

So you may be wondering, what do I need to change?  The only parts of the script which would require modification would be the content type names within $parentCtypes and the XML for the retention policy.  After you have updated the XML for your policy and selected which Content Types to apply the policy to, you simply need to run the script.  The script will prompt you for the root site collection URL.

I actually struggled the most with trying to decipher the correct markup of the XML, the script itself was actually pretty simple.  Again, in order to get the markup for the policy I would create it via the GUI and then find the policy with SharePoint 2013 Manager and view the XML for the policy, it is way easier with a copy paste!  I wasted a ton of time trying to write the XML from scratch and advise you not to do the same!

param($url = $(Read-Host -prompt "Root Site Collection Path"))

#Get the PowerShell Snapin
Add-PSSnapin "Microsoft.SharePoint.PowerShell"

#Search Service Application
$ssa = Get-SPEnterpriseSearchServiceApplication
Write-Host $ssa.Name -ForegroundColor Magenta

#Get Site
$site = Get-SPSite $url

#Get Root Web
$web = $site.RootWeb

#Write Out That The Web Was Found
if($web -ne $null)
{
    Write-Host "The web is" $web "and the site is" $site.HostName -ForegroundColor Magenta

}

#Fill the array with base content types i.e. Exelon Content Page
$parentCtypes = @("Content Page");

foreach ($ctype in $web.ContentTypes)
{
    foreach($i in $parentCtypes)
    {
        if($ctype.Name -eq $i)
        {
            Write-Host $ctype.Name "is the same as" $i -ForegroundColor Magenta
            $ctypePolicy = [Microsoft.Office.RecordsManagement.InformationPolicy.Policy]::GetPolicy($ctype);
            if($ctypePolicy -ne $null)
            {
                Write-Host $ctype.Name "Has an existing Policy" $ctypePolicy "and is being deleted" -ForegroundColor Magenta
                [Microsoft.Office.RecordsManagement.InformationPolicy.Policy]::DeletePolicy($ctype);
            }
            [Microsoft.Office.RecordsManagement.InformationPolicy.Policy]::CreatePolicy($ctype, $null);
            $ctypePolicy = [Microsoft.Office.RecordsManagement.InformationPolicy.Policy]::GetPolicy($ctype);
            $ctypePolicy.Items.Add("Microsoft.Office.RecordsManagement.PolicyFeatures.Expiration",
                "<Schedules nextStageId='2'>"+
                    "<Schedule type='Default'>"+
                        "<stages>"+
                            "<data stageId='1'>"+
                                "<formula id='Microsoft.Office.RecordsManagement.PolicyFeatures.Expiration.Formula.BuiltIn'>"+
                                    "<number>0</number>"+
                                    "<property>ExpirationDate</property>"+
                                    "<propertyId>8c06beca-0777-48f7-91c7-6da68bc07b69</propertyId>"+
                                    "<period>days</period>"+
                                "</formula>"+
                                "<action type='action' id='Microsoft.Office.RecordsManagement.PolicyFeatures.Expiration.Action.Record' />"+
                            "</data>"+
                        "</stages>"+
                    "</Schedule>"+
                "</Schedules>");
                $ctypePolicy.Update();
                $ctype.Update();
            Write-Host "The Policy For" $ctype.Name "Has Been Created And Applied!" -ForegroundColor Green
        }
    }
}

Good Luck!

Dan