8

I have created some custom Roles under the "sitecore" domain, but now I want to migrate all the custom roles to another domain e.g. fancy_domain\Cool_Role. How to do it?

8

I see a few different things need to get this completed.

  1. Reporting: Report on all the items with a role explicitly defined. Simple approach is to find all items referencing a given domain. I wrote a report here that can help.
  2. Bulk Changing: Map the old role to the new role and update the security on each item. The report could either be updated to have actions to do this or write a separate script.

Reporting

Using the gist provided, you can view a report like the following:

Domain Selector

Final Report

Bulk Changing

Using the security commands provided by SPE, you can reassign the security for each item.

Example: The following lists all of the security settings applied to the item.

$item = Get-Item -Path "master:{11111111-1111-1111-1111-111111111111}"
Get-ItemAcl -Item $item

<#
Account                          AccessRight          PermissionType   PropagationType  SecurityPermission
-------                          -----------          --------------   ---------------  ------------------
Everyone                         item:read            Access           Entity           AllowAccess
Everyone                         item:read            Access           Descendants      AllowAccess
sitecore\Everyone                item:read            Access           Entity           AllowAccess
sitecore\Everyone                item:read            Access           Descendants      AllowAccess
#>

Check out these commands:

  • Add-ItemAcl
  • Get-ItemAcl
  • Set-ItemAcl
  • Test-ItemAcl

Turns out the script was less complex than I initially anticipated.

Example: The following updates security to items provided you have mapped the old role to a new role.

<#
    .SYNOPSIS
        Find all items referencing the specified domain and replace with a new domain.

    .NOTES
        Michael West
#>

Import-Function -Name Invoke-SqlCommand

# You'll want to update the domains and role mapping.
$oldDomain = "demo"
$newDomain = "powerful"

$roleMapping = @{
    "demo\Broken Role" = "powerful\Ways Role"
}

$connection = [Sitecore.Configuration.Settings]::GetConnectionString("master")

$securityFieldId = [Sitecore.FieldIDs]::Security

# Find all the items which explicitly have security assigned.
$query = @"
SELECT [ItemId], [Value]
  FROM [dbo].[SharedFields]
  WHERE [FieldId] = '$($securityFieldId.ToString())'
    AND [Value] <> ''
"@

$records = Invoke-SqlCommand -Connection $connection -Query $query
$matchingRecords = $records | Where-Object { $_.Value -match $oldDomain } |
    ForEach-Object { Get-Item -Path "master:" -ID "$($_.ItemId.ToString())" }

foreach($matchingRecord in $matchingRecords) {
    $oldacls = Get-ItemAcl -Item $matchingRecord

    $newacls = @()
    foreach($oldacl in $oldacls) {
        $newacl = New-ItemAcl -AccessRight $oldacl.AccessRight -PropagationType $oldacl.PropagationType -SecurityPermission $oldacl.SecurityPermission -Identity ($roleMapping[$oldacl.Account.Name])
        $newacls += $newacl
    }

    $matchingRecord | Set-ItemAcl -AccessRules $newacls
}

Note: Messages added to output for screenshot.

Sample Output

3

As far as I know this is not supported by ASP .NET membership provider. But here is a similar question: https://stackoverflow.com/questions/281891/how-do-you-rename-a-role-using-membership-in-net

public void RenameRoleAndUsers(string oldRoleName, string newRoleName)
{
    string[] users = Roles.GetUsersInRole(oldRoleName);
    Roles.CreateRole(newRoleName);
    Roles.AddUsersToRole(users, newRoleName);
    Roles.RemoveUsersFromRole(users, oldRoleName);
    Roles.DeleteRole(oldRoleName);
}

The code snippet above only changes the roles of the users. You need an extra step to assign the new role for the items where the old role was used. Here is an example method which can work for 1 item (I did not try it but it is compilable):

public void ChangeItemRole(Item item, string newRole, string oldRole)
{
    var oldAccessRules = item.Security.GetAccessRules();
    var newAccessRules = new AccessRuleCollection();
    foreach (var oldAccessRule in oldAccessRules)
    {
        if (oldAccessRule.Account.Name == oldRole)
        {
            newAccessRules.Add(
                AccessRule.Create(
                    Role.FromName(newRole),
                    oldAccessRule.AccessRight,
                    oldAccessRule.PropagationType,
                    oldAccessRule.SecurityPermission));
        }
        else
        {
            newAccessRules.Add(oldAccessRule);
        }
    }

    item.Security.SetAccessRules(newAccessRules);
}
0

Maybe this script also can be useful. This script copies all access rights from one identity to another indentity for selected item. So you can easy move all access rights for all items.

Copy-ItemAcl -FromIdentity 'SUPER\ROBSONAUTOMATOR' -ToIdentity 'LAZY\ONE' -Path "/sitecore/content/Home"

The full code is available on gist

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.