Export Security Settings

Posted 02/14/2014 by Sean Connall


I am often asked to move data from one environment to another. There are any number of ways to get content out of Sitecore. I use Export Languages from the Globalization Control Panel to get content translated. I use serialization to export anything from templates, layouts, content items to users and roles. This all works great and serves its purpose.

In a typical project life cycle (especially long, multi-phased projects) it is common to have activity taking place in all Sitecore environments (DEV, QA, CM and CD). It is also common for a client to request certain roles and access permissions configured and to then change their minds as they use the system and request us to rework security to better fit the real world usage of Sitecore.

When this situation arises there are two questions that need to be answered:

  1. Where do I make the security updates so the client is not disrupted and they can be verified?
  2. Once complete how do I port the security updates to other environments?

For this particular approach serialization does not provide a viable solution. Serialization is item specific but exports all fields for that item. If the security update is made in the dev environment and the serialized data is then reverted into the CM environment there is potential for content other than the Security (__security) field to be changed. Initially  I thought that the serialized data could be altered to only include the Security field. This did not lead to the results I was hoping for as the revert exited with data inconsistencies due to the missing fields. 

My next thought was to extend the serialization to do what I wanted. What I really needed though was a simple way to get the following data:

  • A list of all items that have security set
  • The GUID for each item to allow importing
  • Raw value for the Security field for each item

These requirements sound a lot like a report don't they?


Enter Advanced System Reporter (available from the Sitecore Marketplace). ASR is one of my all time favorite modules and is a must install for any project I work on. In fact there is already a report in place that meets the first criteria of finding items with security.

The "Items with Security for and account" report is exactly the starting point I needed. Opening this report in ASR shows the following:

Security Report

You can select where you want the report to scan as well as specifying a user or role to look for. leaving the Security Account field blank gets all items with any security applied. 

The output from this report looks like this:

Initial report output

So now I just needed the actual security value and the GUID of the item. 

An ASR report consists of
  • one one or more Scanners that return data
  • one or more Viewers that display the data
  • optional Filters to refine the data.
Since the report already had the scanner I needed I decided to add a new viewer to show the GUID and the security field. After navigating to the /sitecore/system/Modules/ASR/Configuration/Viewer folder I created a new viewer item called ItemAccessSetttings. 

Item Access Viewer

This viewer uses the standard ASR.Reports.Items.ItemViewer class and then some additional settings. In the Viewer section you can edit which columns are added to the report. There are some predefined columns but any field on the item can be entered manually for inclusion. I added the __Security field in this manner.

NOTE: after getting everything working the output was truncated with ellipses for the Security column. The ItemViewer can take a maxlength parameter to increase this. An example is shown above and results in the full data being output to the column and subsequent exported data.

The GUID was not available as a standard field. I figured if i was going to be using ASR to export data in this manner that the GUID might be worth ahving as part of the default field list. This required some very simple customization to the ASR.Reports.Items.ItemViewer class. I had already included the ASR projects in my solution so this was readily accessible.

There were two places that needed updating. The first is AvailableColumns method. This simply returns a string array of values for the menu selection. I added GUID to the bottom

public override string[] AvailableColumns
                return new string[]
                        "GUID" //added GUID

The other method that needed updating was the getColumnText  method. This method uses a case statement for each menu item to return the appropriate data. I added he first case to output the item GUID. I left the remaining items in this post just so you can see what is there

protected virtual string getColumnText(string name, Item itemElement)
            switch (name)
                case "guid":
                    return itemElement.ID.ToString();

                case "name":
                    return itemElement.Name;

                case "displayname":
                    return itemElement.DisplayName;

                case "createdby":
                    return itemElement[FieldIDs.CreatedBy];

                case "updated":
                    return formatDateField(itemElement, FieldIDs.Updated);

                case "updatedby":
                    return itemElement[FieldIDs.UpdatedBy];

                case "created":
                    return formatDateField(itemElement, FieldIDs.Created);

                case "lockedby":
                    LockField lf = itemElement.Fields["__lock"];
                    var text = "unlocked";
                    if (lf != null)
                        if (!string.IsNullOrEmpty(lf.Owner))
                            text = lf.Owner + " " + lf.Date.ToString("dd/MM/yy HH:mm");
                    return text;
                case "template":
                    return itemElement.Template.Name;

                case "path":
                    return itemElement.Paths.FullPath;

                case "owner":
                    return itemElement[FieldIDs.Owner];

                case "workflow":
                    return getWorkflowInfo(itemElement);

                case "childrencount":
                    return itemElement.Children.Count.ToString();

                case "version":
                    return itemElement.Version.ToString();

                case "versions":
                    return itemElement.Versions.Count.ToString();

                case "language":
                    return itemElement.Language.CultureInfo.DisplayName;
                    return GetFriendlyFieldValue(name, itemElement);

The last piece was to add my new viewer to the existing report. Since ASR can take more than one viewer I simply added the ItemAccessRights viewer I just defined to the existing report.

Add viewer

The output now looks like this:

Updated report with GUID and security

Using the XML export gives me the following (excerpt only):


7/25/2013 2:04 PM
/sitecore/content/United States/Home/Tiles
ar|sitecore\News Events Author|pe|!*|pd|!*|ar|sitecore\Investors Author|pe|!*|pd|!*|

Now that I have exactly the data I want it is just a matter of importing it into the desired environment......but that is another blog post.

If you have not used ASR give it a try. I have been a fan for a long time.