I have always struggled with SPMT PowerShell because the use is not really intuitive and comparing to UI tool it does not offer so many options. One of the things that really bothered me was hot to migrate a SharePoint web or sub web to a new site collection and I found out that only option is to use JSON tasks to be able to achieve this.
# Path to the CSV file with source-target pairs
$csvPath = "C:\temp\Allwebs.csv"
# Import CSV and specify column headers
$pairs = Import-Csv -Path $csvPath -Delimiter ";"
# Define common settings for each task
$settings = @{
MigrateFileVersionHistory = $true
KeepAllVersions = $true
MigrateHiddenItems = $true
PreservePermission = $true
EnableIncremental = $true
MigrateOneNoteNotebook = $true
}
# Initialize task list
$tasks = @()
# Build tasks from CSV input
foreach ($pair in $pairs) {
$task = @{
SourcePath = $pair.SourcePath
TargetPath = $pair.TargetPath
Settings = $settings
Items=@{ SubSites = @() }
}
$tasks += $task
}
# Wrap in the main JSON structure
$jsonObject = @{ Tasks = $tasks }
# Convert to JSON string with depth for nested objects
$jsonOutput = $jsonObject | ConvertTo-Json -Depth 5
# Output JSON to file
$outputPath = "C:\temp\migration_tasks-1.json"
$jsonOutput | Out-File -Encoding UTF8 -FilePath $outputPath
Write-Host "Migration JSON file created: $outputPath"
This code goes through a list of SharePoint webs that you intent to migrate and creates a JSON task to initiate the migration.
After you have the JSON file created, you can actually use SPMT PowerShell module and start you migration. The script is as follows:
Import-Module Microsoft.SharePoint.MigrationTool.PowerShell
$onpremCred=Get-Credential -Message "Enter On-prem creds"
$spoCred=Get-Credential -Message "Enter SPO Creds"
#Register the SPMT session with SPO credentials#
Register-SPMTMigration -SPOCredential $spoCred -Force -MigrateAllSiteFieldsAndContentTypes $true -MigrateFileVersionHistory $true -KeepAllVersions $true `
-AutomaticUserMapping $true -PreserveUserPermissionsForSharePointSource $true -MigrateSiteSettings ONLY_TITLE_LOGO -WorkingFolder C:\SPMT -LookupReferencePolicy FIND_ALL_REFERENCE `
-DisableNoScriptDuringMigration $true -MigrateNavigation $true
$jsonItems = Get-Content -Raw -Path "C:\temp\migration_tasks-1.json" | ConvertFrom-Json
ForEach ($taskItem in $jsonItems.Tasks)
{
$jsonString = ConvertTo-Json $taskItem -Depth 100
Add-SPMTTask -JsonDefinition $jsonString -SharePointSourceCredential $onpremCred
}
$timer=[System.Diagnostics.Stopwatch]::StartNew()
$timer.Start()
Start-SPMTMigration -NoShow
$session = Get-SPMTMigration
# Query migration status every 5 seconds until migration is finished
while ($session.Status -ne "Finished")
{
Write-Host "Session status: $($session.Status) | Task count: $i" -BackgroundColor Yellow -ForegroundColor Black
$i=1
# Query migration progress of each tasks
Foreach ($taskStatus in $session.StatusOfTasks)
{
if($($taskStatus.MigratingProgressPercentage) -ne 100){
Write-Host "$($taskStatus.SourceURI ) => $($taskStatus.TargetURI) Complete: $($taskStatus.MigratingProgressPercentage)% | Scanned: $($taskStatus.NumScannedTotalFiles) | ToMig: $($taskStatus.NumFileWillBeMigrated) | ActualMig: $($taskStatus.NumActuallyMigratedFiles)"
Add-Content -Value "$($taskStatus.SourceURI ) => $($taskStatus.TargetURI) Complete: $($taskStatus.MigratingProgressPercentage)% | Scanned: $($taskStatus.NumScannedTotalFiles) | ToMig: $($taskStatus.NumFileWillBeMigrated) | ActualMig: $($taskStatus.NumActuallyMigratedFiles)" `
-Path "C:\SPMTLog\MigLog-$(Get-Date -uformat "%Y-%m-%d").txt"
$i++
}
}
Write-Host "$("-"*50)" -BackgroundColor Yellow -ForegroundColor Black
Start-Sleep -Seconds 60
}
$timer.Stop()
$timer.Elapsed
Hope it helps someone with SPMT migrations.
Leave a comment