Migrating Sitecore Roles Using Powershell

Fun Fact: Simply packaging Sitecore roles up doesn’t really move them.

Sitecore’s use of the .NET Membership Provider (I’m guessing) means that user roles behave oddly when doing things like serializing or packaging them. This is because all of the info about a given role doesn’t actually live on that role’s record.

The “Member Of” information about a role is stored on the role that a given role is a member of, as opposed to on the member role. This means that if you serialize (including using TDS) or package a role, the data about what role that role belongs to does not come along with it.

This can be very frustrating when trying to deploy roles to different environments and keep them consistent. Yes, you could theoretically package up all the roles but that exposes another fun quirk of the role system: you cannot update existing roles when you install a package containing them. That, of course, is a rather annoying issue because the most common use of roles, at least in my experience, is to bundle up a bunch of default Sitecore roles to ease user management. In that scenario, Sitecore won’t update the existing role with your new role data.

There’s a better solution than simply manually recreating your role inheritance in new environments: Sitecore Powershell Extensions.

I love SPE. In fact, my clients all know just what I’m talking about when I refer to “my girlfriend”. In this case, SPE lets us solve the problem using our old friend the CSV file.

I created a script that lets you get a bunch of roles using SPE’s Get-Role Filter option and then export all of the roles that those roles inherit into a CSV file (using the List-View window’s CSV export button). That script gets run on the source environment.

$filters = @()

$filters += "extranet\TA Digital *"
$filters += "sitecore\TA Dogital *"

$roles = @()
foreach ($filter in $filters)
 $roles +=Get-Role -Filter $filter

$rolesToExport = @()
foreach ($role in $roles){
 Write-Host $role.Name
 $thisRolesRoles = Get-Role -Identity $role.Name | Select-Object -ExpandProperty MemberOf
 foreach ($rolesRole in $thisRolesRoles){
 Write-Host $rolesRole.Name -F Yellow
 $myObject = $null
 $myObject = New-Object System.Object
 $myObject | Add-Member -Type NoteProperty -Name RoleName -Value $role.Name.ToString()
 $myObject | Add-Member -Type NoteProperty -Name InheritedRoleName -Value $rolesRole.Name.ToString()
 $rolesToExport += $myObject

$rolesToExport | Show-ListView

I then created another script that uses that exported CSV to create any missing roles and also update the role inheritance according to the exported values. You run this script on the target environment and feed it the CSV you just created.

$dataFolder = [Sitecore.Configuration.Settings]::DataFolder
$tempFolder = $dataFolder + "\temp\upload\userimport"
$filePath = Receive-File -Path $tempFolder -Overwrite

$itemCount = 0;
$processedItemCount = 0;
$errorCount = 0;
$warningCount = 0;
$logInfo = "";
$errorDump = "";

$resultSet = Import-Csv $filePath

$rowsCount = ($resultSet | Measure-Object).Count;

if ($rowsCount -le 0) {
 Remove-Item $filePath
 Write-Host "Zero Records Found in CSV $filePath" -f Red
 Write-Log $logInfo;

"Records -----------------"
Write-Host $rowsCount.ToString() " Roles to update";
" "
foreach ($row in $resultSet) {

 $roleName = $row.RoleName.Trim();
 $InheritedRoleName = $row.InheritedRoleName.Trim();
 if (Test-Account $roleName) { 
 Write-Host $itemCount . Adding $roleName to $InheritedRoleName -f Green
 Add-RoleMember -Members $roleName -Identity $InheritedRoleName
 } else {
 Write-Host $itemCount . Adding $roleName and adding to $InheritedRoleName -f Yellow
 New-Role -Identity $roleName | Out-Null
 Add-RoleMember -Members $roleName -Identity $InheritedRoleName


Remove-Item $filePath

Write-Host "Process Complete"

Write-Host $itemCount.ToString() "Roles Processed" -ForegroundColor Cyan

if ($errorCount -gt 0) {
 Write-Host $errorCount.ToString() "Errors Encountered" -ForegroundColor Red
} else {
 Write-Host $errorCount.ToString() "Errors Encountered" -ForegroundColor Green
if ($warningCount -gt 0) {
 Write-Host $warningCount.ToString() "Warnings Encountered" -ForegroundColor Yellow
} else {
 Write-Host $warningCount.ToString() "Warnings Encountered" -ForegroundColor Green

Write-Host ""
Write-Host ""


This was all built for a specific use, but I’m sure I’ll need it again and odds are other Sitecore practitioners out there will too. Of course it couldn’t have been done without the wonderful tool that the SPE team has created. Thanks guys!!

About The Author