Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
This report helps identify all of the items with explicit security set for a given domain. Sitecore PowerShell Extensions.
<#
.SYNOPSIS
Find all items referencing the specified domain.
.DESCRIPTION
This report helps identify all of the items with explicit security set for a given domain.
.NOTES
Michael West
#>
Import-Function -Name Invoke-SqlCommand
$domainOptions = Get-Domain | ForEach-Object { $options = [ordered]@{} } { $options[$_.Name]=$_.Name } { $options }
$settings = @{
Title = "Report Filter"
Width = "350"
Height = "250"
OkButtonName = "Proceed"
CancelButtonName = "Abort"
Description = "Filter items explicitly referencing the specified domain."
Parameters = @(
@{
Name="selectedDomain";
Options=$domainOptions
Title="Choose a domain for the report";
Tooltip="Only items matching security with this domain will be returned.";
}
)
}
$result = Read-Variable @settings
if($result -ne "ok") {
Exit
}
$connection = [Sitecore.Configuration.Settings]::GetConnectionString("master")
$securityFieldId = [Sitecore.FieldIDs]::Security
# Find all the items which explicitly hae security assigned.
$query = @"
SELECT [ItemId], [Value]
FROM [dbo].[SharedFields]
WHERE [FieldId] = '$($securityFieldId.ToString())'
AND [Value] <> ''
"@
$records = Invoke-SqlCommand -Connection $connection -Query $query
$reportProperties = @{
Property = @("Name", "Id", "ItemPath", @{Name="Security";Expression={$_."__Security"}})
Title = "Items assigned with explicit domain security"
InfoTitle = "Items assigned with explicit domain security"
InfoDescription = "Items which reference the domain '$($selectedDomain)'."
}
$records | Where-Object { $_.Value -match $selectedDomain } |
ForEach-Object { Get-Item -Path "master:" -ID "$($_.ItemId.ToString())" } |
Show-ListView @reportProperties
<#
.SYNOPSIS
Find all items referencing the specified domain and replace with a new domain.
.NOTES
Michael West
#>
Import-Function -Name Invoke-SqlCommand
$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 hae 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
Write-Host "Original ACLs" -ForegroundColor Yellow
$oldacls | Out-Default
$newacls = @()
foreach($oldacl in $oldacls) {
$newacl = New-ItemAcl -AccessRight $oldacl.AccessRight -PropagationType $oldacl.PropagationType -SecurityPermission $oldacl.SecurityPermission -Identity ($roleMapping[$oldacl.Account.Name])
$newacls += $newacl
}
Write-Host ""
Write-Host "New ACLs" -ForegroundColor Yellow
$newacls | Out-Default
Write-Host ""
Write-Host "Updated item" -ForegroundColor Yellow
$matchingRecord | Set-ItemAcl -AccessRules $newacls -PassThru
}
@melker

This comment has been minimized.

Copy link

@melker melker commented Aug 30, 2019

Tip: In order to speed it up you should filter on the domain already in the sql query:

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

I wanted to search for user in the domain named "ad", you should replace it with the variable.

Also the -match should add a backslash at the end of the domain, or there are a lot of false hits when using such a common string as "ad".

@michaellwest

This comment has been minimized.

Copy link
Owner Author

@michaellwest michaellwest commented Aug 30, 2019

Thanks for the tip @melker, that does seem to help quite a bit. No need to pull back so many records only to discard them.

I went with this query:

$query = @"
SELECT [ItemId], [Value]
  FROM [dbo].[SharedFields]
  WHERE [FieldId] = '$($securityFieldId.ToString())'
	AND [Value] <> '' AND [Value] LIKE '%|$($selectedDomain)%'
"@
@michaellwest

This comment has been minimized.

Copy link
Owner Author

@michaellwest michaellwest commented Aug 30, 2019

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment