DifferentialMigration/vSphere/VMBasedDifferentialMigration.psm1
using module '../../Common/Result' Import-Module -Name @(Join-Path $PSScriptRoot .. | Join-Path -ChildPath DifferentialMigration) function Start-RMInteractiveVSphereVMBasedDifferentialMigration { param() $UserInput = @{} $OrganizationId = Get-Variable -Name "RMContext-CurrentProjectId" -ValueOnly $Migration, $Source = Read-RMFullMigrationId -VMBasedSourceRequired $true $UserInput.Add("Migration", $Migration) $UserInput.Add("Source", $Source) [RMMigrationReturn] $RMMigrationReturn = [RMMigrationReturn]::new() if ((Test-RMSourceHasRunningMigration -OrganizationId $OrganizationId -SourceId $Source.id)) { $UserMessage = "Currently there is a migration running for the source of the given migration ID, this differential migration might fail." Write-Warning $UserMessage $RMMigrationReturn.AddRMWarning([RMWarning]::new($UserMessage)) } $ScheduledAt = Read-RMMigrationSchedule -IsDifferentialMigration $true $TransferMode = "run-once" if ("Continuous" -ieq $ScheduledAt) { $TransferMode = "continuous" $ScheduledAt = "" } else { $UpgradeTools = Read-RMBoolean -UserMessage "Do you want to upgrade the VM tools on the target VM" -DefaultValue "false" $ShutdownSource = Read-RMBoolean -UserMessage "Shutdown source after data is fully migrated" -DefaultValue "false" $ShutdownTarget = Read-RMBoolean -UserMessage "Shutdown target after data is fully migrated" -DefaultValue "false" $UserInput.Add("UpgradeTools", $UpgradeTools) $UserInput.Add("ShutdownSource", $ShutdownSource) $UserInput.Add("ShutdownTarget", $ShutdownTarget) } $UserInput.Add("ScheduledAt", $ScheduledAt) $UserInput.Add("TransferMode", $TransferMode) $FinalizeMigration = Read-RMBoolean -UserMessage "Remove snapshot(s) from the Target VM in preparation for a cutover" -DefaultValue "false" $UserInput.Add("FinalizeMigration", $FinalizeMigration) $ReadValue = Read-RMPair -UserMessage "Enter one or more migration instructions in the format 'key=value', separated by commas" ` -Separator "=" -DefaultValue "None" $MigrationInstructions = Get-RMStringAsHashtable -InputString $ReadValue $UserInput.Add("MigrationInstruction", $MigrationInstructions) $IgnoreValidationErrors = Read-RMBoolean -UserMessage "Ignore validation errors" -DefaultValue "false" $UserInput.Add("IgnoreValidationErrors", $IgnoreValidationErrors) $Response = New-RMVMBasedDifferentialProfile @UserInput $ShouldExit = Start-RMDifferentialMigrationPreflight -DifferentialProfileId $Response.id ` -IgnoreValidationErrors $IgnoreValidationErrors -RMMigrationReturn $RMMigrationReturn if ($ShouldExit) { return $RMMigrationReturn } $IsScheduled = ![string]::IsNullOrWhiteSpace($ScheduledAt) $MigrationResponse = Invoke-RMDifferentialMigrationPost -DifferentialProfileResponse $Response return Update-RMMigrationReturnAsSuccess -MigrationResponse $MigrationResponse ` -RMMigrationReturn $RMMigrationReturn -IsScheduledMigration $IsScheduled ` -ReturnMessage "Differential migration started successfully, migration ID" } function Start-RMNonInteractiveVsphereVMBasedDifferentialMigration { param ( [System.Guid] $MigrationId, [string] $ScheduledAt, [bool] $RunContinuous, [bool] $UpgradeTools, [bool] $ShutdownSource, [bool] $ShutdownTarget, [bool] $FinalizeMigration, [string[]] $MigrationInstruction, [bool] $IgnoreValidationErrors ) $UserInput = @{} [RMMigrationReturn] $RMMigrationReturn = [RMMigrationReturn]::new() $Errors, $IsValidMigrationId = Confirm-RMVMBasedDMCommonParameter -UserParameter $PSBoundParameters if (!$IsValidMigrationId) { $RMMigrationReturn.SetReturnCode([RMReturn]::ERROR) $Errors | ForEach-Object -Process {$RMMigrationReturn.AddRMError([RMError]::new($_))} Out-RMUserParameterResult -ErrorMessage $Errors return $RMMigrationReturn } $Migration = Get-RMMigrationByIdAndStatus -MigrationId $MigrationId $UserInput.Add("Migration", $Migration) $Source, $ErrorString = Confirm-RMSource -SourceId $Migration.source_id if ("" -ne $ErrorString) { $Errors += $ErrorString } $UserInput.Add("Source", $Source) $ErrorsInMigrationObject, $Warnings = Confirm-RMVMBasedDMParameterWithMigrationAndSource -UserParameter $PSBoundParameters ` -Migration $Migration -Source $Source $Errors += $ErrorsInMigrationObject $TransferMode, $ScheduledAt = Get-RMTransferModeAndSchedule -RunContinuous $RunContinuous -ScheduledAt $ScheduledAt $MigrationInstructionAsHashTable = @{} try { if (![string]::IsNullOrWhiteSpace($MigrationInstruction)) { $MigrationInstructionAsHashTable = Get-RMStringArrayAsHashtable -InputItems $MigrationInstruction -ParameterName "MigrationInstruction" } } catch { $Errors += $PSItem.Exception.Message } if ($Errors.Count -gt 0 -or $Warnings.Count -gt 0) { $Errors | ForEach-Object -Process {$RMMigrationReturn.AddRMError([RMError]::new($_))} $Warnings | ForEach-Object -Process {$RMMigrationReturn.AddRMWarning([RMWarning]::new($_))} Out-RMUserParameterResult -ErrorMessage $Errors -WarningMessage $Warnings if ($Errors.Count -gt 0) { $RMMigrationReturn.SetReturnCode([RMReturn]::ERROR) return $RMMigrationReturn } } $UserInput.Add("TransferMode", $TransferMode) $UserInput.Add("ScheduledAt", $ScheduledAt) $UserInput.Add("UpgradeTools", $UpgradeTools) $UserInput.Add("ShutdownSource", $ShutdownSource) $UserInput.Add("ShutdownTarget", $ShutdownTarget) $UserInput.Add("FinalizeMigration", $FinalizeMigration) $UserInput.Add("MigrationInstruction", $MigrationInstructionAsHashTable) $UserInput.Add("IgnoreValidationErrors", $IgnoreValidationErrors) $Response = New-RMVMBasedDifferentialProfile @UserInput $ShouldExit = Start-RMDifferentialMigrationPreflight -DifferentialProfileId $Response.id ` -IgnoreValidationErrors $IgnoreValidationErrors -RMMigrationReturn $RMMigrationReturn if ($ShouldExit) { return $RMMigrationReturn } $IsScheduled = ![string]::IsNullOrWhiteSpace($ScheduledAt) $MigrationResponse = Invoke-RMDifferentialMigrationPost -DifferentialProfileResponse $Response return Update-RMMigrationReturnAsSuccess -MigrationResponse $MigrationResponse ` -RMMigrationReturn $RMMigrationReturn -IsScheduledMigration $IsScheduled ` -ReturnMessage "Differential migration started successfully, migration ID" } function Confirm-RMVMBasedDMParameterWithMigrationAndSource { param( [hashtable] $UserParameter, [System.Object] $Migration, [System.Object] $Source ) $Errors = @() $Warnings = @() $HeartbeatStatus = Test-RMApplianceHeartbeating -ApplianceId $Migration.cloud_appliance_id -AccountType $Migration.target_cloud_type if (!$HeartbeatStatus) { $Errors += "Migration appliance is not ready, cannot start differential migration; please make sure that the migration appliance is ready for use and then try again." } $OrganizationId = Get-Variable -Name "RMContext-CurrentProjectId" -ValueOnly if ((Test-RMSourceHasRunningMigration -OrganizationId $OrganizationId -SourceId $Source.id)) { $Warnings += "Currently there is a migration running for the source of the given migration ID, this differential migration might fail." } $MigrationType = $Migration.migration_type if ("full" -ne $MigrationType) { $Errors += "Migration type for the given migration ID is '$MigrationType', differential migration can only be started for a full migration." } if ($null -ne $Source -and $Source.collection_type -ine "vm") { $IPAddress = $Source.host $Errors += "The source with IP address '$IPAddress' is not a VM based source, please use the cmdlet 'Start-RMOSBasedDifferentialMigration' to start a differential migration for this source." } return $Errors, $Warnings } |