Content Migration Using Scripts
A recent project required the migration of specific content to a new Sitecore instance. The task involved processing an Excel sheet containing item IDs designated for migration. While the objective appeared straightforward, it necessitated a methodical and efficient approach to ensure accuracy and reliability. Here’s the process I followed.
The first step was to make the Excel file accessible within the Sitecore environment. To achieve this, the file was converted into a CSV format and uploaded to the Media Library in a designated folder.
Subsequently, a PowerShell script was developed to automate the process. This script iterated through each row of the CSV file, retrieved the item IDs, fetched the corresponding items from Sitecore, and added them to the package source. In my case the requirement was for migrating a few blogs from an old Sitecore instance to our new QA environment.
PowerShell Script for Content Migration
# Configuration
$mediaItemPath = "/sitecore/media library/script/blog-migration"
$packageName = "Blog-Items-Package"
$packageVersion = "1.0"
$packageAuthor = "Anju Thomas"
try {
Write-Host "Creating package & metadata..."
# Create and configure package
$package = New-Package $packageName
$package.Sources.Clear()
$package.Metadata.Author = $packageAuthor
$package.Metadata.Version = $packageVersion
$package.Metadata.Readme = "Package containing items from CSV file"
# Get media item
$mediaItem = Get-Item -Path $mediaItemPath -Language "en" -ErrorAction Stop
if (-not $mediaItem) {
throw "Media item not found at path: $mediaItemPath"
}
Write-Host "Processing CSV file..."
# Get media stream and create temporary file
$mediaStream = [Sitecore.Resources.Media.MediaManager]::GetMedia([Sitecore.Data.Items.MediaItem]$mediaItem).GetStream().Stream
$tempFilePath = [System.IO.Path]::GetTempFileName()
# Process items in a bulk context for better performance
New-UsingBlock (New-Object Sitecore.Data.BulkUpdateContext) {
# Copy stream to temp file
$fileStream = [System.IO.File]::Create($tempFilePath)
$mediaStream.CopyTo($fileStream)
$fileStream.Close()
# Read and process CSV
$importList = Import-Csv -Path $tempFilePath
$totalItems = $importList.Count
$processedItems = 0
foreach ($row in $importList) {
$processedItems++
Write-Progress -Activity "Processing Items" -Status "Processing item $processedItems of $totalItems" -PercentComplete (($processedItems / $totalItems) * 100)
try {
$item = Get-Item -Path "master:" -ID $row.ID -ErrorAction Stop
if ($item) {
Write-Host "Adding item to package: $($item.Name) ($($row.ID))"
$source = $item | New-ItemSource -Name $item.Name -InstallMode Overwrite
$package.Sources.Add($source)
}
}
catch {
Write-Warning "Could not find item with ID: $($row.ID)"
}
}
}
Write-Host "Exporting package..."
# Export package
$packagePath = "$($package.Name)-$($package.Metadata.Version).zip"
Export-Package -Project $package -Path $packagePath -Zip
# Offer download
Write-Host "Package created successfully. Initiating download..."
Download-File "$SitecorePackageFolder\$packagePath"
}
catch {
Write-Error "An error occurred: $_"
throw
}
finally {
# Cleanup
if ($null -ne $mediaStream) { $mediaStream.Dispose() }
if ($null -ne $fileStream) { $fileStream.Dispose() }
if (Test-Path $tempFilePath) { Remove-Item $tempFilePath -Force }
}
Script Highlights
Package Metadata
The script begins by initializing a new Sitecore package with essential metadata, including the package name, version, and author.
Retrieving the CSV File
Next, the script fetches the CSV file stored in the Media Library using a specified path. The file is then copied to a temporary location for further processing.
Bulk Processing
To handle items efficiently, the script uses the BulkUpdateContext. It reads each row from the CSV file and retrieves the corresponding item from the Sitecore database using the provided ID.
Adding Items to the Package
For each valid item retrieved, the script adds it to the package source. The items are added with an 'Overwrite' installation mode, so during installation, it doesn’t prompt for an action each time.
Exporting the Package
Once all items have been added, the script exports the package as a ZIP file. This file is then ready for download and could be installed in the target environment.
Cleanup
Finally, the script disposes of temporary files and streams to prevent memory leaks and ensure no lingering temporary data remains.
At the end of the process, the package is ready for download, as shown in the screenshot.
Content Migration Simplified
This script simplifies Sitecore content migration when you have a list of items to transfer. It can easily be adapted to fetch related items for each blog, ensuring that all associated media mentioned in fields are also included in the migration package. This flexibility makes the script a powerful tool for comprehensive content migrations.