Migration/AZURE/AZURE.psm1
Import-Module -Name $PSScriptRoot\..\..\MigrationProfile\AzureMigrationProfile Import-Module -Name $PSScriptRoot\..\..\Preflight\Preflight Import-Module -Name $PSScriptRoot\..\..\Util\Util Import-Module -Name $PSScriptRoot\..\..\CloudAccount\CloudAccount Import-Module -Name $PSScriptRoot\..\..\Source\Source Import-Module -Name $PSScriptRoot\..\..\Source\SourceUtil\SourceUtil function Start-RMAzureOSBasedInteractiveMigration { param() $UserInput = @{} $CloudAccountName = Read-Host "Enter cloud account name" if ("" -eq $CloudAccountName) { throw "Cloud account name is required to start a migration." } $CloudAccount = Get-RMCloudAccountByName -CloudAccountName $CloudAccountName $RefreshCloudAttributes = $false $ReadValue = Read-Host "Refresh cloud attributes (true/false)[false]" if ("" -ne $ReadValue) { $RefreshCloudAttributes = [System.Convert]::ToBoolean($ReadValue) } $CloudAttributes = Get-RMCloudAttribute -CloudAccount $CloudAccount -RefreshCloudAttributes $RefreshCloudAttributes $Entitlement = Get-RMEntitlement $UserInput.Add("CloudAccount", $CloudAccount) $UserInput.Add("CloudAttributes", $CloudAttributes) $UserInput.Add("Entitlement", $Entitlement) $SourceIP = Read-Host "Enter the IP address of the source machine to be migrated" if ("" -eq $SourceIP) { throw "Source IP address is required to start a migration." } $RefreshSourceAttributes = $false $ReadValue = Read-Host "Refresh source attributes (true/false)[false]" if ("" -ne $ReadValue) { $RefreshSourceAttributes = [System.Convert]::ToBoolean($ReadValue) } $Source = Get-RMSourceWithAttribute -IPAddress $SourceIP -RefreshSourceAttributes $RefreshSourceAttributes $UserInput.Add("Source", $Source) $TargetVMName = $Source.hostname $ReadValue = Read-Host "Enter target VM Name [$TargetVMName]" if ("" -ne $ReadValue) { $TargetVMName = $ReadValue } $UserInput.Add("TargetVMName", $TargetVMName) $TransferMethod = "file-based" if ("windows" -ieq $Source.os_type) { $ReadValue = Read-Host "Enter transfer method (file-based/block-based)[file-based]" if ("" -ne $ReadValue) { $TransferMethod = $ReadValue } } $UserInput.Add("TransferMethod", $TransferMethod) $ResourceGroupRegion = "" $ReadValue = Read-Host "Create a new resource group (true/false)[false]" if ("" -ne $ReadValue) { $ReadValue = [System.Convert]::ToBoolean($ReadValue) if ($ReadValue) { $ResourceGroup = Read-Host "Enter the name of the resource group to be created" if ("" -eq $ResourceGroup) { throw "Resource group name is required, please try again." } $ResourceGroupRegion = Read-Host "Enter the region name where the resource group will be created" if ("" -eq $ResourceGroupRegion) { throw "Resource group region name is required, please try again." } } else { $ResourceGroup = Get-ExistingResourceGroupNameFromUser -CloudAccount $CloudAccount } } else { $ResourceGroup = Get-ExistingResourceGroupNameFromUser -CloudAccount $CloudAccount } $UserInput.Add("ResourceGroup", $ResourceGroup) $UserInput.Add("ResourceGroupRegion", $ResourceGroupRegion) $VMSizeName = Read-Host "Enter VM Size name" if ("" -eq $VMSizeName) { throw "VM Size is required, please try again" } $VMSize = Get-VMSizeByName -VMSizeName $VMSizeName -CloudAttributes $CloudAttributes if ($null -eq $VMSize) { throw "VM size by name '$VMSizeName' does not exists." } $UserInput.Add("VMSize", $VMSize) $DiskTypeMappings = @() $ReturnedValue = Get-DiskTypeMappingBySource -Source $Source -VMSize $VMSize -IsInteractive $true if ($ReturnedValue -is [hashtable]) { # The method "Get-DiskTypeMappingBySource" returns an array of hashtables, but it # has been observed that if the source contains a single disk, the returned value # is of type HashTable; hence we are checking the type and re-adding it to an array $DiskTypeMappings += $ReturnedValue } else { $DiskTypeMappings = $ReturnedValue } $UserInput.Add("DiskTypeMappings", $DiskTypeMappings) $MountPoints = Get-MountPoint -Source $Source if (0 -eq $MountPoints.count) { throw "Source has no mount points, cannot be migrated" } $MountPointsAsString = $MountPoints.values -join ", " Write-Output "Mount points to be migrated [$MountPointsAsString]" $ExcludedMountPoints = Get-RMExcludedMountPoint -Source $Source $SelectedMountPoints = $MountPoints if ("" -ne $ExcludedMountPoints) { $ExcludedList = $ExcludedMountPoints.Split(",").Trim() $SelectedMountPoints = Get-RMSelectedMount -MountPoints $MountPoints -DifferenceList $ExcludedList -IncludeEqual $false } $UserInput.Add("MountPoints", $SelectedMountPoints) $ReadValue = Read-Host "Resize mount points (true/false) [false]" $MountsResize = @{} if ("" -ne $ReadValue) { $ReadValue = [System.Convert]::ToBoolean($ReadValue) if ($ReadValue) { $ResizeMounts = @{} $MountPointList = @() $SelectedMountPoints | ForEach-Object { $MountPointList += $_.values } $SourceMountPointObjects = Get-RMMountPointObject -Source $Source foreach ($Mount in $MountPointList) { foreach ($MountPoint in $SourceMountPointObjects) { if ($MountPoint.path -ne $Mount) { continue } $TotalSpace = [math]::round($MountPoint.size_kb/(1024 * 1024), 2) $UsedSpace = [math]::round($MountPoint.used_kb/(1024 * 1024), 2) $ReadValue = Read-Host "Enter new size in GiB for mount point $Mount (used space $UsedSpace of $TotalSpace)[$TotalSpace]" if ("" -ne $ReadValue) { $ResizeMounts.Add($Mount, $ReadValue) } break } } if ($ResizeMounts.Count -gt 0) { $MountsResize = Add-RMResizeMount -SelectedMounts $MountPointList -ResizeMounts $ResizeMounts -Source $Source if ($null -eq $MountsResize) { return } } } } $UserInput.Add("MountsResize", $MountsResize) $DataTransferPort = 5995 if ("windows" -ieq $Source.os_type) { $ReadValue = Read-Host "Enter data transfer port [5995]" if ("" -ne $ReadValue) { $DataTransferPort = $ReadValue } } $UserInput.Add("DataTransferPort", $DataTransferPort) $VirtualNetwork = $CloudAccount.appliance.cloud_properties.virtual_network.name $ReadValue = Read-Host "Enter virtual network name [$VirtualNetwork]" if ("" -ne $ReadValue) { $VirtualNetwork = $ReadValue } $UserInput.Add("VirtualNetwork", $VirtualNetwork) $Subnet = $CloudAccount.appliance.cloud_properties.network.interfaces.eth0.network_name $ReadValue = Read-Host "Enter subnet name [$Subnet]" if ("" -ne $ReadValue) { $Subnet = $ReadValue } $UserInput.Add("Subnet", $Subnet) $AssignPublicIP = $false $ReadValue = Read-Host "Auto assign public IP (true/false)[false]" if ("" -ne $ReadValue) { $AssignPublicIP = [System.Convert]::ToBoolean($ReadValue) } $UserInput.Add("AssignPublicIP", $AssignPublicIP) $StaticPrivateIP = Read-Host "Enter static private IP to be assigned to target [None]" $UserInput.Add("StaticPrivateIP", $StaticPrivateIP) $EnforceTargetNetworkIsolation = $true $ReadValue = Read-Host "Enforce target network isolation (true/false)[true]" if ("" -ne $ReadValue) { $EnforceTargetNetworkIsolation = [System.Convert]::ToBoolean($ReadValue) } $SecurityGroup = $null if (!$EnforceTargetNetworkIsolation) { $ReadValue = Read-Host "Enter security group name" if ("" -ne $ReadValue) { $SecurityGroup = $ReadValue } } $UserInput.Add("SecurityGroup", $SecurityGroup) $DisableTargetDNSRegistration = $false if("windows" -ieq $Source.os_type) { $ReadValue = Read-Host "Disable automatic DNS registration (true/false)[false]" if ("" -ne $ReadValue) { $DisableTargetDNSRegistration = [System.Convert]::ToBoolean($ReadValue) } } $UserInput.Add("DisableTargetDNSRegistration", $DisableTargetDNSRegistration) $ReadValue = Read-Host "Enter one or more instance tags in the format 'key=value' and separated by commas [None]" $InstanceTags = Get-RMStringAsHashtable -InputString $ReadValue $UserInput.Add("InstanceTags", $InstanceTags) $AvailabilitySet = $null $AvailabilityZone = $null $FaultDomainCount = $null $UpdateDomainCount = $null $ReadValue = Read-Host "Enter availability option (None, AvailabilityZone, AvailabilitySet)[None]" if ("" -ne $ReadValue -and "none" -ine $ReadValue) { if (-not ("None" -ieq $ReadValue -or "AvailabilityZone" -ieq $ReadValue -or "AvailabilitySet" -ieq $ReadValue)) { throw "Invalid availability option entered, please try again" } if ("AvailabilityZone" -ieq $ReadValue) { $AvailabilityZones = $VMSize.availability_zones -join ", " $AvailabilityZone = Read-Host "Enter the availability zone ($AvailabilityZones)" if ("" -eq "AvailabilityZone") { throw "Availability zone is required when 'AvailabilityZone' is the selected availability option" } } else { $ReadValue = Read-Host "Create a new availability set (true/false)[false]" if ("" -ne $ReadValue) { $ReadValue = [System.Convert]::ToBoolean($ReadValue) if ($ReadValue) { $AvailabilitySet = Read-Host "Enter the name of the availability set to be created" if ("" -eq $AvailabilitySet) { throw "Availability set name is required, please try again." } $FaultDomainCount = "2" $ReadValue = Read-Host "Enter fault domains (1-3)[2]" if ("" -ne $ReadValue) { $FaultDomainCount = $ReadValue } $UpdateDomainCount = "5" $ReadValue = Read-Host "Enter update domains (1-20)[5]" if ("" -ne $ReadValue) { $UpdateDomainCount = $ReadValue } } else { $AvailabilitySet = Get-ExistingAvailabilitySetNameFromUser -CloudAttributes $CloudAttributes -ResourceGroup $ResourceGroup } } else { $AvailabilitySet = Get-ExistingAvailabilitySetNameFromUser -CloudAttributes $CloudAttributes -ResourceGroup $ResourceGroup } } } $UserInput.Add("AvailabilityZone", $AvailabilityZone) $UserInput.Add("AvailabilitySet", $AvailabilitySet) $UserInput.Add("FaultDomainCount", $FaultDomainCount) $UserInput.Add("UpdateDomainCount", $UpdateDomainCount) $EnableBootDiagnostics = $false $StorageAccount = $null $ReadValue = Read-Host "Enable boot diagnostics (true/false)[false]" if ("" -ne $ReadValue) { $EnableBootDiagnostics = [System.Convert]::ToBoolean($ReadValue) } if ($EnableBootDiagnostics) { $ReadValue = Read-Host "Enter azure storage account name for boot diagnostics" if ("" -eq $ReadValue) { throw "Storage account name is required for enabling boot diagnostics" } else { $StorageAccount = $ReadValue } } $UserInput.Add("EnableBootDiagnostics", $EnableBootDiagnostics) $UserInput.Add("StorageAccount", $StorageAccount) $EncryptionSet = $null $ReadValue = Read-Host "Enter disk encryption type (platform-managed/customer-managed)[platform-managed]" if ("" -ne $ReadValue) { if (-not ("platform-managed" -ieq $ReadValue -or "customer-managed" -ieq $ReadValue)) { throw "Invalid disk encryption type entered, please try again" } if ("customer-managed" -ieq $ReadValue) { $ReadValue = Read-Host "Enter encryption set name" if ("" -eq $ReadValue) { throw "Encryption set name is required for the selected encryption type" } $EncryptionSet = $ReadValue } } $UserInput.Add("EncryptionSet", $EncryptionSet) $EnableHybridUseBenefit = $false if("windows" -ieq $Source.os_type) { $ReadValue = Read-Host "Enable Azure hybrid use benefit (true/false)[false]" if ("" -ne $ReadValue) { $EnableHybridUseBenefit = [System.Convert]::ToBoolean($ReadValue) } } $UserInput.Add("EnableHybridUseBenefit", $EnableHybridUseBenefit) $SourceOSMMapping = Get-RMOSMMappingBySource -Source $Source $OSMLabels = $SourceOSMMapping.keys -join ", " $ReadValue = Read-Host "Enter the OS version to upgrade to ($OSMLabels)[None]" if ("" -ne $ReadValue) { $ReadValue = $ReadValue.Trim('"') $ReadValue = $ReadValue.Trim("'") if ($SourceOSMMapping.keys -notcontains $ReadValue) { throw "Please enter one of $OSMLabels and try again" } $UserInput.Add("UpgradeOSVersion", $SourceOSMMapping[$ReadValue]) $UserInput.Add("InPlaceUpgrade", $true) } else { $UserInput.Add("UpgradeOSVersion", $null) $UserInput.Add("InPlaceUpgrade", $false) } $ShutdownSource = $false $ReadValue = Read-Host "Shutdown source after data is fully migrated (true/false)[false]" if ("" -ne $ReadValue) { $ShutdownSource = [System.Convert]::ToBoolean($ReadValue) } $UserInput.Add("ShutdownSource", $ShutdownSource) $ShutdownTarget = $false $ReadValue = Read-Host "Shutdown target after data is fully migrated (true/false)[false]" if ("" -ne $ReadValue) { $ShutdownTarget = [System.Convert]::ToBoolean($ReadValue) } $UserInput.Add("ShutdownTarget", $ShutdownTarget) $RemoveRMSAgent = $false $ReadValue = Read-Host "Remove RMS agent post migration (true/false)[false]" if ("" -ne $ReadValue) { $RemoveRMSAgent = [System.Convert]::ToBoolean($ReadValue) } $UserInput.Add("RemoveRMSAgent", $RemoveRMSAgent) $ReadValue = Read-Host "Enter migration instructions in the format 'key=value' and separated by commas [None]" $MigrationInstructions = Get-RMStringAsHashtable -InputString $ReadValue $UserInput.Add("MigrationInstructions", $MigrationInstructions) $Response = New-RMAzureMigrationProfile @UserInput $RMLoginResult = Get-Variable -Name "RMContext-UserLogin" $Uri = Get-Variable -Name "RMContext-ReactorURI" $Headers = @{ Accept = "application/rm+json" "X-Auth-Token" = $RMLoginResult.Value.token } $Params = @{ Method = "Post" Uri = $Uri.Value + "/migrationprofiles/" + $Response.id + "/migrations" Headers = $Headers ContentType = "application/json" } Invoke-RMRestMethod -Params $Params | Out-Null } function Start-RMAzureOSBasedNonInteractiveMigration { param( [string] $CloudAccountName, [string] $SourceIP, [bool] $RefreshSourceAttributes, [string] $TargetVMName, [string] $TransferMethod, [bool] $CreateResourceGroup, [string] $ResourceGroup, [string] $ResourceGroupRegion, [string] $VMSizeName, [string] $VolumeType, [string[]] $MountPoints, [string[]] $ResizeMountPoints, [int] $DataTransferPort, [string] $VirtualNetwork, [string] $Subnet, [bool] $AssignPublicIP, [string] $StaticPrivateIP, [bool] $EnforceTargetNetworkIsolation, [string] $SecurityGroup, [bool] $DisableTargetDNSRegistration, [string[]] $InstanceTags, [string] $AvailabilityOptions, [int] $AvailabilityZone, [bool] $CreateAvailabilitySet, [string] $AvailabilitySet, [int] $FaultDomains, [int] $UpdateDomains, [bool] $EnableBootDiagnostics, [string] $StorageAccount, [string] $DiskEncryptionType, [string] $EncryptionSet, [bool] $EnableHybridUseBenefit, [string] $UpgradeOSVersion, [bool] $ShutdownSource, [bool] $ShutdownTarget, [bool] $RemoveRMSAgent, [string[]] $MigrationInstructions ) $Entitlement = Get-RMEntitlement $UserInput = @{} $CloudAccount = Get-RMCloudAccountByName -CloudAccountName $CloudAccountName $CloudAttributes = Get-RMCloudAttribute -CloudAccount $CloudAccount -RefreshCloudAttributes $false $UserInput.Add("CloudAccount", $CloudAccount) $UserInput.Add("CloudAttributes", $CloudAttributes) $UserInput.Add("Entitlement", $Entitlement) $Source = Get-RMSourceWithAttribute -IPAddress $SourceIP -RefreshSourceAttributes $RefreshSourceAttributes $UserInput.Add("Source", $Source) $UserInput.Add("TargetVMName", $TargetVMName) $UserInput.Add("TransferMethod", $TransferMethod) if ($CreateResourceGroup) { if ("" -eq $ResourceGroupRegion) { throw "Resource group region is required, when parameter 'CreateResourceGroup' is true." } } $UserInput.Add("ResourceGroup", $ResourceGroup) $UserInput.Add("ResourceGroupRegion", $ResourceGroupRegion) $VMSize = Get-VMSizeByName -VMSizeName $VMSizeName -CloudAttributes $CloudAttributes if ($null -eq $VMSize) { throw "VM size by name '$VMSizeName' does not exists." } $UserInput.Add("VMSize", $VMSize) if ("" -eq $VolumeType) { $VolumeType = "Standard_SSD" } $UserInput.Add("VolumeType", $VolumeType) $SourceMountPoints = Get-MountPoint -Source $Source Compare-RMMountPoint -Source $Source -SourceMountPoints $SourceMountPoints -UserInputMountPoints $MountPoints $SelectedMountPoints = Get-RMSelectedMount -MountPoints $SourceMountPoints -DifferenceList $MountPoints -IncludeEqual $true $UserInput.Add("MountPoints", $SelectedMountPoints) $MountsResize = @{} if ("" -ne $ResizeMountPoints) { $ResizeMounts = Get-RMStringArrayAsHashtable -InputItems $ResizeMountPoints $MountPointList = @() foreach ($SelectedMountPoint in $SelectedMountPoints) { $MountPointList += $SelectedMountPoint.values } $MountsResize = Add-RMResizeMount -SelectedMounts $MountPointList -ResizeMounts $ResizeMounts -Source $Source if ($null -eq $MountsResize) { # validation errors, hence return return } } $UserInput.Add("MountsResize", $MountsResize) $UserInput.Add("DataTransferPort", $DataTransferPort) $UserInput.Add("VirtualNetwork", $VirtualNetwork) $UserInput.Add("Subnet", $Subnet) $UserInput.Add("AssignPublicIP", $AssignPublicIP) $UserInput.Add("StaticPrivateIP", $StaticPrivateIP) if (!$EnforceTargetNetworkIsolation) { $UserInput.Add("SecurityGroup", $SecurityGroup) } if("windows" -ieq $Source.os_type) { $UserInput.Add("DisableTargetDNSRegistration", $DisableTargetDNSRegistration) } else { $UserInput.Add("DisableTargetDNSRegistration", $false) } $InstanceTagsAsHashTable = Get-RMStringArrayAsHashtable -InputItems $InstanceTags $UserInput.Add("InstanceTags", $InstanceTagsAsHashTable) if ("AvailabilitySet" -ieq $AvailabilityOptions) { if ("" -eq $AvailabilitySet) { throw "Availability set name is required." } $UserInput.Add("AvailabilitySet", $AvailabilitySet) $UserInput.Add("AvailabilityZone", "") if ($CreateAvailabilitySet) { if (0 -eq $FaultDomains) { throw "Fault domains is required, when parameter 'CreateAvailabilitySet' is true." } elseif (-not($FaultDomains -ge 1 -and $FaultDomains -le 3)) { throw "Fault domains should be in the range 1 and 3." } if (0 -eq $UpdateDomains) { throw "Update domains is required, when parameter 'CreateAvailabilitySet' is true." } elseif (-not($UpdateDomains -ge 1 -and $UpdateDomains -le 20)) { throw "Update domains should be in the range 1 and 20." } $UserInput.Add("FaultDomainCount", $FaultDomains.ToString()) $UserInput.Add("UpdateDomainCount", $UpdateDomains.ToString()) }else { $UserInput.Add("FaultDomainCount", $null) $UserInput.Add("UpdateDomainCount", $null) } } elseif("AvailabilityZone" -ieq $AvailabilityOptions) { if (-not($AvailabilityZone -ge 1 -and $AvailabilityZone -le 3)) { throw "AvailabilityZone should be in the range 1 and 3." } else { $UserInput.Add("AvailabilityZone", $AvailabilityZone.ToString()) } $UserInput.Add("AvailabilitySet", "") $UserInput.Add("FaultDomainCount", $null) $UserInput.Add("UpdateDomainCount", $null) } $UserInput.Add("EnableBootDiagnostics", $EnableBootDiagnostics) $UserInput.Add("StorageAccount", $StorageAccount) if ("customer-managed" -ieq $DiskEncryptionType -and "" -eq $EncryptionSet) { throw "Encryption set is required when disk encryption type is 'customer-managed'" } $UserInput.Add("EncryptionSet", $EncryptionSet) if("windows" -ieq $Source.os_type) { $UserInput.Add("EnableHybridUseBenefit", $EnableHybridUseBenefit) } else { $UserInput.Add("EnableHybridUseBenefit", $false) } if ("" -ne $UpgradeOSVersion) { $SourceOSMMapping = Get-RMOSMMappingBySource -Source $Source $OSMLabels = $SourceOSMMapping.keys -join ", " $UpgradeOSVersion = $UpgradeOSVersion.Trim('"') $UpgradeOSVersion = $UpgradeOSVersion.Trim("'") if ($SourceOSMMapping.keys -notcontains $UpgradeOSVersion) { throw "Please enter one of '$OSMLabels' and try again" } $UserInput.Add("UpgradeOSVersion", $SourceOSMMapping[$UpgradeOSVersion]) $UserInput.Add("InPlaceUpgrade", $true) } else { $UserInput.Add("UpgradeOSVersion", $null) $UserInput.Add("InPlaceUpgrade", $false) } $UserInput.Add("ShutdownSource", $ShutdownSource) $UserInput.Add("ShutdownTarget", $ShutdownTarget) $UserInput.Add("RemoveRMSAgent", $RemoveRMSAgent) $MigrationInstructionsAsHashTable = Get-RMStringArrayAsHashtable -InputItems $MigrationInstructions $UserInput.Add("MigrationInstructions", $MigrationInstructionsAsHashTable) $Response = New-RMAzureMigrationProfile @UserInput $RMLoginResult = Get-Variable -Name "RMContext-UserLogin" $Uri = Get-Variable -Name "RMContext-ReactorURI" $Headers = @{ Accept = "application/rm+json" "X-Auth-Token" = $RMLoginResult.Value.token } $Params = @{ Method = "Post" Uri = $Uri.Value + "/migrationprofiles/" + $Response.id + "/migrations" Headers = $Headers ContentType = "application/json" } Invoke-RMRestMethod -Params $Params | Out-Null } function Get-RMAvailabilitySet { param( [System.Object] $CloudAttributes, [string] $ResourceGroup ) if ($null -eq $CloudAttributes -or 0 -eq $CloudAttributes.properties.subscriptions.Count -or 0 -eq $CloudAttributes.properties.subscriptions[0].regions) { throw "Internal error, cloud attributes doesn't exist" } $AvailabilitySets = @() foreach ($AvailabilitySet in $CloudAttributes.properties.subscriptions[0].regions[0].availability_sets) { if ($AvailabilitySet.resource_group -eq $ResourceGroup) { $AvailabilitySets += $AvailabilitySet.name } } return $AvailabilitySets } function Get-ExistingResourceGroupNameFromUser { param( [System.Object] $CloudAccount ) $ResourceGroup = $CloudAccount.appliance.cloud_properties.resource_group $ReadValue = Read-Host "Enter existing resource group name [$ResourceGroup]" if ("" -ne $ReadValue) { $ResourceGroup = $ReadValue } return $ResourceGroup } function Get-ExistingAvailabilitySetNameFromUser { param( [System.Object] $CloudAttributes, [string] $ResourceGroup ) $AvailabilitySets = Get-RMAvailabilitySet -CloudAttributes $CloudAttributes -ResourceGroup $ResourceGroup $AvailabilitySetsAsString = $AvailabilitySets -join ", " $AvailabilitySet = Read-Host "Enter the existing availability set name ($AvailabilitySetsAsString)" if ("" -eq $AvailabilitySet) { throw "Availability set name is required based on the selected availability option." } return $AvailabilitySet } Export-ModuleMember -Function Start-RMAzureOSBasedInteractiveMigration, Start-RMAzureOSBasedNonInteractiveMigration |