Last active
November 4, 2025 18:26
-
-
Save MartinMiles/5b18e93d78684d895979b483336644ce to your computer and use it in GitHub Desktop.
Iterate through you sitecore environment and replace all the texts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # Minimal SPE find and replace across Single-Line Text, Multi-Line Text, Rich Text | |
| # Static inputs | |
| $FindText | |
| $ReplaceText | |
| $ScopePaths = "/sitecore/content" # comma separated for multiple roots, for example "/sitecore/content/SiteA, /sitecore/content/SiteB" | |
| $CaseSensitive = $true | |
| $DryRun = $false | |
| if ([string]::IsNullOrWhiteSpace($FindText)) { throw "Find cannot be empty." } | |
| # Prepare scope | |
| $paths = $ScopePaths -split "," | ForEach-Object { $_.Trim() } | Where-Object { $_ } | |
| if (-not $paths) { $paths = "/sitecore/content" } | |
| # Prepare regex | |
| $pattern = [regex]::Escape($FindText) | |
| $regexOptions = if ($CaseSensitive) { [System.Text.RegularExpressions.RegexOptions]::None } else { [System.Text.RegularExpressions.RegexOptions]::IgnoreCase } | |
| # Field types to update | |
| $allowedTypes = @("Single-Line Text","Multi-Line Text","Rich Text") | |
| # Counters | |
| $totalItems = 0 | |
| $itemsChanged = 0 | |
| $fieldsChanged = 0 | |
| $errCount = 0 | |
| # Database | |
| $database = "master" | |
| $stopwatch = [System.Diagnostics.Stopwatch]::StartNew() | |
| # Collect all items under scope, all languages, all versions | |
| $items = foreach ($root in $paths) { | |
| Get-ChildItem -Path "$database`:$root" -Recurse -Language * -ErrorAction SilentlyContinue | |
| } | |
| if (-not $items) { Write-Host "No items found in scope."; return } | |
| Write-Host "Scanning $($items.Count) items in $database. DryRun=$DryRun CaseSensitive=$CaseSensitive" | |
| # Faster bulk update and disable security | |
| $bulk = New-Object Sitecore.Data.BulkUpdateContext | |
| $sec = New-Object Sitecore.SecurityModel.SecurityDisabler | |
| try { | |
| foreach ($item in $items) { | |
| $totalItems++ | |
| if ($item.Paths.Path -like "/sitecore/system*") { continue } | |
| $itemHadHits = $false | |
| $fieldHitsOnItem = 0 | |
| $versions = $item.Versions.GetVersions($true) | |
| if (-not $versions -or $versions.Count -eq 0) { $versions = @($item) } | |
| foreach ($ver in $versions) { | |
| $editStarted = $false | |
| foreach ($field in $ver.Fields) { | |
| if ($null -eq $field) { continue } | |
| if ($field.ReadOnly) { continue } | |
| if ($field.Type -notin $allowedTypes) { continue } | |
| $current = [string]$field.Value | |
| if ([string]::IsNullOrEmpty($current)) { continue } | |
| if ([regex]::IsMatch($current, $pattern, $regexOptions)) { | |
| $newValue = [regex]::Replace($current, $pattern, [System.Text.RegularExpressions.MatchEvaluator]{ param($m) $ReplaceText }, $regexOptions) | |
| if (-not $DryRun) { | |
| if (-not $ver.Editing.IsEditing) { $ver.Editing.BeginEdit() | Out-Null; $editStarted = $true } | |
| $field.Value = $newValue | |
| } | |
| $itemHadHits = $true | |
| $fieldHitsOnItem++ | |
| } | |
| } | |
| if ($editStarted -and $ver.Editing.IsEditing) { | |
| $ver.Editing.EndEdit() | Out-Null | |
| } | |
| } | |
| if ($itemHadHits) { | |
| $fieldsChanged += $fieldHitsOnItem | |
| $itemsChanged++ | |
| Write-Host "[HIT] $($item.Paths.Path) [$($item.Language)] fields: $fieldHitsOnItem" | |
| } | |
| if ($totalItems % 200 -eq 0) { | |
| $pct = [int](100 * $totalItems / [math]::Max(1, $items.Count)) | |
| Write-Progress -Activity "Processing items" -Status "$totalItems scanned, $itemsChanged items with hits" -PercentComplete $pct | |
| } | |
| } | |
| } | |
| catch { | |
| $errCount++ | |
| Write-Warning "Error: $_" | |
| } | |
| finally { | |
| if ($bulk) { $bulk.Dispose() } | |
| if ($sec) { $sec.Dispose() } | |
| $stopwatch.Stop() | |
| } | |
| Write-Host "" | |
| Write-Host "Done. Scanned items: $totalItems" | |
| Write-Host "Items with hits: $itemsChanged" | |
| Write-Host "Field replacements: $fieldsChanged" | |
| Write-Host "Dry run: $DryRun" | |
| Write-Host "Elapsed: $([int]$stopwatch.Elapsed.TotalSeconds)s" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment