Public/Start-TenantConverge.ps1
|
function Start-TenantConverge { <# .SYNOPSIS Starts TenantConverge: sets up a consolidation of 1, 2 or 3 source tenants into 1 target tenant and assesses them. .DESCRIPTION Without parameters, it asks for the scenario and saves the answers to a project file. With -Project, it reads an existing project file and asks nothing. Then it checks the prerequisites, connects and collects the tenants, read-only, computes the migration plan, writes consolidation-report.html and consolidation-workbook.xlsx in the output folder, and opens the report. It never writes to a tenant. A module that only one workload needs does not stop the run: the coverage of the snapshot says what was not collected. Without ImportExcel, there is no workbook. Use -Install to install what is missing first. .PARAMETER Project An existing project file to read instead of asking the setup questions. .PARAMETER Path The project file to create. The default is ./project.json. .PARAMETER Force Replaces an existing project file. .PARAMETER Install Installs or updates the missing modules for the current user before the assessment. .PARAMETER NoOpen Leaves the report closed at the end. .EXAMPLE Start-TenantConverge Asks the setup questions, saves ./project.json, then assesses the tenants. .EXAMPLE Start-TenantConverge -Project ./project.json Reads an existing project and assesses the tenants, without any question. #> [CmdletBinding(SupportsShouldProcess)] [OutputType([pscustomobject])] param( [string]$Project, [string]$Path = './project.json', [switch]$Force, [switch]$Install, [switch]$NoOpen ) if ($Project) { $projectPath = $Project $loaded = Read-TcProjectFile -Path $Project Write-TcMessage -Message "Project loaded: $(Get-TcProperty $loaded 'name')" -Level Success } else { if ((Test-Path -LiteralPath (Resolve-TcPath -Path $Path)) -and -not $Force) { throw "The file '$Path' already exists. Use -Force to replace it, or -Project to read it." } $loaded = Invoke-TcWizard if ($null -eq $loaded) { Write-TcMessage -Message 'Nothing was saved.' return } Assert-TcNoProjectProblem -Problem @(Test-TcProjectDefinition -Project $loaded) if (-not $PSCmdlet.ShouldProcess($Path, 'Write project file')) { return $loaded } Write-TcProjectFile -Project $loaded -Path $Path Write-TcMessage -Message 'Project saved.' -Level Success $projectPath = $Path } $prerequisites = if ($Install) { Test-TcPrerequisite -Install } else { Test-TcPrerequisite } if ($prerequisites.PowerShell -and [version]($prerequisites.PowerShell -replace '-.*$', '') -lt [version]'7.4') { throw "PowerShell $($prerequisites.PowerShell) is too old. Version 7.4 or later is required." } if (@($prerequisites.Missing) -contains 'Microsoft.Graph.Authentication') { throw 'Microsoft Graph is required for every workload. Run Test-TcPrerequisite -Install, then start again.' } $noWorkbook = @($prerequisites.Missing) -contains 'ImportExcel' $notCollected = @(@($prerequisites.Missing) | Where-Object { $_ -ne 'ImportExcel' }) if ($notCollected.Count -gt 0) { Write-TcMessage -Message "Missing, so not collected: $($notCollected -join ', '). Run Test-TcPrerequisite -Install to add them." -Level Warning } if ($noWorkbook) { Write-TcMessage -Message 'ImportExcel is missing, so there will be no workbook. Run Test-TcPrerequisite -Install to add it.' -Level Warning } $assessment = Invoke-TcAssessment -Project $projectPath Write-TcMessage -Message "Snapshot: $($assessment.Snapshot)" $plan = Get-TcProperty $assessment 'Plan' if ($plan) { Write-TcMessage -Message "Plan: $plan" } $output = Write-TcProjectOutput -Project $projectPath -Assessment $assessment -SkipWorkbook:$noWorkbook if ($output.Report -and -not $NoOpen) { Open-TcReport -Path $output.Report } if ((Get-TcProperty (Get-TcProperty $loaded 'access') 'mode') -eq 'Application') { Write-TcMessage -Message "The read-only application stays in each tenant. At the end of the project, remove it with Remove-TcAccess -Project '$projectPath'." -Level Warning } $loaded } |