Automatically move VMs from anywhere & to anywhere in Azure:
- Move VMs across subscriptions
- Move VMs across tenants
- In the same region or across regions
- No downtime on the source VM (if there’s no data disks), the source VM remains in-tact
- Copies both the OS disk and any data disks attached to the VM
- Both Standard & Premium managed disks supported
Works with ARM Managed Disk based VMs only. This script is fully automatic and cleans up temp disks & storage accounts at the very end. It shows the copy process and doesn’t waste time by coping white space on disks (e.g. if you had a 1023GB disk and only 1GB was in use, the time it takes to copy 1GB of data). If you had multiple data disks attached to a VM, this script keeps a track of the disk LUN numbers, when you re-attach the disks at the end using the Azure portal, you simply attach the data disks in the order of the LUN number specified on the data disks.
Instructions:
- Run the script
- It prompts you for source & target credentials & subscriptions
- prompts you to select a source VM from a list of managed disk based VMs
- prompts you to select a target region from a list of Azure regions
- prompts you to enter a target resource group
- It will prompt you to shut down the source VM if there’s data disks, it can’t possibly copy all the disks in sync, the end state will be un-comprehensible.
This script sets up the target resource group along with exact copies of managed disks from the source VM. The script uses its own naming convention for the target disks as per the screenshot above (with the date tacked on the end). From there, you manually create the new VM using the Azure portal and attach the disks back to the VM and follow the process of creating a normal VM in the Azure portal.
In the Azure portal on the OS managed disk blade, choose the option to ‘Create VM‘ and and follow your nose to create a VM in the Azure portal, then attach any data disks in the order of LUN IDs specified in the data disk display names (starting at xero).
If you have issues with the script below (errors etc), check first the very top line and install the same PowerShell module that I wrote the script with.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<# | |
Written with version 2.8.0 of the Azure PowerShell Module | |
available from here https://github.com/Azure/azure-powershell/releases/tag/v2.8.0-October2019 | |
or run: Install-Module -Name Az -RequiredVersion 2.6.0 -AllowClobber | |
Migration instructions Azure.RM to Az – https://azure.microsoft.com/en-au/blog/how-to-migrate-from-azurerm-to-az-in-azure-powershell/ | |
#> | |
# from https://poshtools.com/2018/04/10/cross-platform-out-gridview-using-universal-dashboard/ | |
function Out-GridView | |
{ | |
<# | |
.SYNOPSIS | |
Send objects to Out-Gridview in Windows PowerShell | |
.DESCRIPTION | |
This command is intended as a workaround for PowerShell Core running on a Windows platform, presumably Windows 10. PowerShell Core does not support all of the .NET Framework which means some commands like Out-Gridview are not supported. However, on a Windows desktop you are most likely running Windows PowerShell side by side with PowerShell Core. This command is designed to take objects from a PowerShell expression and send it to an instance of Windows PowerShell running Out-Gridview. You can specify a title and pass objects back to your PowerShell Core session. Note that passed objects will be deserialized versions of the original objects. | |
.PARAMETER Title | |
Specify a Title for the Out-Gridview window | |
.PARAMETER Passthru | |
Pass selected objects from Out-Gridview back to your PowerShell Core session. | |
.EXAMPLE | |
PS C:\> get-childitem c:\scripts\*.ps1 | Send-ToPSGridview -title "My Scripts" | |
Press Enter to continue…: | |
Display all ps1 files in Out-Gridview. You must press Enter to continue. | |
.EXAMPLE | |
PS C:\> get-service | where status -eq 'running' | Send-ToPSGridView -Passthru | Restart-service -PassThru | |
Press Enter to continue…: | |
Status Name DisplayName | |
—— —- ———– | |
Running BluetoothUserSe… Bluetooth User Support Service_17b710 | |
Running Audiosrv Windows Audio | |
Get all running services and pipe to Out-Gridview where you can select services which will be restarted. | |
.EXAMPLE | |
PS C:\> $val = 1..10 | Send-ToPSGridView -Title "Select some numbers" -Passthru | |
Press Enter to continue…: | |
PS C:\> $val | |
4 | |
8 | |
6 | |
PS C:\> $val | Measure-Object -sum | |
Count : 3 | |
Average : | |
Sum : 18 | |
Maximum : | |
Minimum : | |
StandardDeviation : | |
Property : | |
Send the numbers 1 to 10 to Out-Gridview where you can select a few. The results are saved to a variable in the PowerShell Core session where you can use them. | |
.INPUTS | |
System.Object | |
.OUTPUTS | |
None, Deserialized.System.Object[] | |
.NOTES | |
Learn more about PowerShell: http://jdhitsolutions.com/blog/essential-powershell-resources/ | |
#> | |
[cmdletbinding()] | |
[alias("ogv")] | |
[OutputType("None", "Deserialized.System.Object[]")] | |
Param( | |
[Parameter(Position = 0, ValueFromPipeline, Mandatory)] | |
[ValidateNotNullOrEmpty()] | |
[object[]]$InputObject, | |
[ValidateNotNullOrEmpty()] | |
[string]$Title = "Out-GridView", | |
[switch]$Passthru | |
) | |
Begin { | |
Write-Verbose "[$((Get-Date).TimeofDay) BEGIN ] Starting $($myinvocation.mycommand)" | |
#validate running on a Windows platform` | |
if ($PSVersionTable.Platform -ne 'Win32NT') { | |
Throw "This command requires a Windows platform with a graphical operating system like Windows 10." | |
} | |
#initialize an array to hold pipelined objects | |
$data = @() | |
#save foreground color | |
$fg = $host.ui.RawUI.ForegroundColor | |
} #begin | |
Process { | |
Write-Verbose "[$((Get-Date).TimeofDay) PROCESS] Adding object" | |
$data += $InputObject | |
} #process | |
End { | |
Write-Verbose "[$((Get-Date).TimeofDay) END ] Creating a temporary xml file with the data" | |
$tempFile = Join-Path –path $env:temp –ChildPath ogvTemp.xml | |
$data | Export-Clixml –Path $tempFile | |
Write-Verbose "[$((Get-Date).TimeofDay) END ] Starting up a PowerShell.exe instance" | |
PowerShell.exe –nologo –noprofile –command { | |
param([string]$Path, [string]$Title = "Out-Gridview", [bool]$Passthru) | |
Import-Clixml –Path $path | Out-Gridview –title $Title –passthru:$Passthru | |
#a pause is required because if you don't use -Passthru the command will automatically complete and close | |
$host.ui.RawUI.ForegroundColor = "yellow" | |
Pause | |
} –args $tempFile, $Title, ($passthru -as [bool]) | |
if (Test-Path –Path $tempFile) { | |
Write-Verbose "[$((Get-Date).TimeofDay) END ] Removing $tempFile" | |
Remove-Item –Path $tempFile | |
} | |
#restore foreground color | |
$host.ui.RawUI.ForegroundColor = $fg | |
Write-Verbose "[$((Get-Date).TimeofDay) END ] Ending $($myinvocation.mycommand)" | |
} #end | |
} #close Send-ToPSGridView | |
########################################################################################## | |
######################## Migration Motivation & Direction ######################### | |
########################################################################################## | |
#region Migration Motivation | @marckean | |
#creating object os WScript | |
$wshell = New-Object –ComObject Wscript.Shell –ErrorAction Stop | |
$SourceTargetAccount = $null # Yes = 6, No = 7 | |
$SourceTargetAccount = $wshell.Popup("Do you use the same logon account to access both Source & Target subscriptions?",0,"Hello User?",48+4) | |
########################################################################################## | |
############################ Logon to Source & Target ############################# | |
########################################################################################## | |
#region Logon to Source & Target environment | @marckean | |
$TargetUserProfile = $null | |
if ($SourceTargetAccount -eq '7') { # Yes = 6, No = 7 | |
# Logon to Source environment | @marckean | |
cls | |
Write-Host "`nEnter credentials for the SOURCE Azure subscription.`n" –ForegroundColor Cyan | |
$SourcePath = "$($env:TEMP)\$(Get-Date –Format yyyyMMdd)SourceEnv.json" | |
Remove-Item –Path $SourcePath –Force –ErrorAction SilentlyContinue | |
#Clear-AzContext -Scope CurrentUser;Clear-AzContext -Scope Process | |
Connect-AzAccount | |
$SourceSubscriptionList = Get-AzSubscription | |
$SourceSubscription = ($SourceSubscriptionList | Out-GridView –Title "Choose a Source Subscription …" –PassThru) | |
Select-AzSubscription –Subscription $SourceSubscription | |
Save-AzContext –Path $SourcePath –Force | |
# Logon to Target environment | @marckean | |
Write-Host "`nEnter credentials for the TARGET Azure subscription.`n" –ForegroundColor Cyan | |
$TargetPath = "$($env:TEMP)\$(Get-Date –Format yyyyMMdd)TargetEnv.json" | |
Remove-Item –Path $TargetPath –Force –ErrorAction SilentlyContinue | |
#Clear-AzContext -Scope CurrentUser;Clear-AzContext -Scope Process | |
Connect-AzAccount | |
$TargetSubscriptionList = Get-AzSubscription | |
$TargetSubscription = ($TargetSubscriptionList | Out-GridView –Title "Choose a Target Subscription …" –PassThru) | |
Select-AzSubscription –Subscription $TargetSubscription | |
Save-AzContext –Path $TargetPath –Force | |
} | |
else { | |
# Logon to Azure environment | @marckean | |
Write-Host "`nEnter credentials for the SOURCE Azure subscription.`n" –ForegroundColor Cyan | |
$SourcePath = "$($env:TEMP)\$(Get-Date –Format yyyyMMdd)SourceEnv.json" | |
$TargetPath = "$($env:TEMP)\$(Get-Date –Format yyyyMMdd)TargetEnv.json" | |
Remove-Item –Path $SourcePath –Force –ErrorAction SilentlyContinue | |
Remove-Item –Path $TargetPath –Force –ErrorAction SilentlyContinue | |
#Clear-AzContext -Scope CurrentUser;Clear-AzContext -Scope Process | |
Connect-AzAccount | |
$SubscriptionList = Get-AzSubscription | |
#Source Subscription | |
$SourceSubscription = ($SubscriptionList | Out-GridView –Title "Choose a Source Subscription …" –PassThru) | |
Select-AzSubscription –Subscription $SourceSubscription | |
Save-AzContext –Path $SourcePath –Force | |
#Target Subscription | |
$TargetSubscription = ($SubscriptionList | Out-GridView –Title "Choose a Target Subscription …" –PassThru) | |
Select-AzSubscription –Subscription $TargetSubscription | |
Save-AzContext –Path $TargetPath –Force | |
} | |
#endregion | |
########################################################################################## | |
################################### Functions #################################### | |
########################################################################################## | |
#region Azure Subscription Functions | @marckean | |
Function SourceSubscription {Import-AzContext –Path $SourcePath} | |
Function TargetSubscription {Import-AzContext –Path $TargetPath} | |
function MDtoSAStoMD { | |
TargetSubscription | |
# Check to see if the target disk already exists | |
if (!(Get-AzDisk –ResourceGroupName $targetResourceGroupName –DiskName $ManagedDisk.TargetName –ea SilentlyContinue)) { | |
SourceSubscription | |
# Get a copy of the current managed disk while VM is in use to use as a temp disk | |
if ($ShutDownDirection -eq '7' -or !$ShutDownDirection) { | |
# Create a TEMP managed disk of the running VM in the same region | |
$TempSourceDiskName = ('TEMP_' + $ManagedDisk.SourceName) | |
# Create temp copy of the original disk | |
$diskConfig = New-AzDiskConfig –SourceResourceId $managedDisk.Id –Location $managedDisk.Location –CreateOption Copy | |
New-AzDisk –Disk $diskConfig –DiskName $TempSourceDiskName –ResourceGroupName $managedDisk.ResourceGroupName | |
$sas = Grant-AzDiskAccess –ResourceGroupName $ManagedDisk.ResourceGroupName –DiskName $TempSourceDiskName ` | |
–DurationInSecond 3600 –Access Read | |
} | |
if ($ShutDownDirection -eq '6') { # Yes = 6, No = 7 | |
$sas = Grant-AzDiskAccess –ResourceGroupName $ManagedDisk.ResourceGroupName –DiskName $ManagedDisk.SourceName ` | |
–DurationInSecond 3600 –Access Read | |
} | |
TargetSubscription | |
$StorageAccount = New-AzStorageAccount –Name (Get-Random –Minimum 11111111111111 –Maximum 99999999999999) ` | |
–ResourceGroupName $TargetResourceGroupName –SkuName Standard_LRS –Location $TargetLocation | |
$StorageAccountKey = Get-AzStorageAccountKey –ResourceGroupName $StorageAccount.ResourceGroupName ` | |
–Name $StorageAccount.StorageAccountName | |
$destContext = New-AzStorageContext –StorageAccountName $StorageAccount.StorageAccountName ` | |
–StorageAccountKey ($StorageAccountKey).Value[0] | |
#Ensure the container is created to store the OS VHD | @marckean | |
$containerName = 'vhds' | |
if (!(Get-AzStorageContainer –Context $destContext | where {$_.Name -eq $containerName})) { | |
cls | |
Write-Verbose "Container $containerName not found. Creating…" | |
New-AzStorageContainer –Context $destContext –Name $containerName –Permission Off | |
} | |
$blob = Start-AzStorageBlobCopy –AbsoluteUri $sas.AccessSAS –DestContainer 'vhds' ` | |
–DestContext $destContext –DestBlob ($ManagedDisk.TargetName + ".vhd") | |
# Retrieve the current status of the copy operation | @marckean | |
$status = $blob | Get-AzStorageBlobCopyState | |
Start-Sleep 5; $status; Start-Sleep 5; $status | |
Write-Host "`n`tCopying the Managed Disk" $ManagedDisk.SourceName "…" –ForegroundColor Cyan | |
#Loop until complete | @marckean | |
While ($status.Status -eq "Pending") { | |
$status = $blob | Get-AzStorageBlobCopyState | |
Start-Sleep 10 | |
#Print out status | |
Write-Host "`n`tCopying the Managed Disk…" –ForegroundColor Cyan | |
$status | Out-Host | |
} | |
# Create the managed disk – convert storage based VHD to a managed disk | |
$VHDContainer = Get-AzStorageContainer –Context $destContext –ErrorAction SilentlyContinue | ? {$_.Name -like $containerName} | |
$BlobEndPoint = (Get-AzStorageBlob –Container $containerName –Context $destContext | | |
? {$_.Name -match ($ManagedDisk.TargetName)}).Context.BlobEndPoint | |
$AzsrcUri = "{0}{1}/{2}" -f $BlobEndPoint, $VHDContainer.Name, (($ManagedDisk.TargetName) + ".vhd") | |
$diskConfig = New-AzDiskConfig –AccountType $ManagedDisk.AccountType –Location $TargetLocation ` | |
–CreateOption Import –SourceUri $AzsrcUri –StorageAccountId $StorageAccount.Id ` | |
–DiskSizeGB $ManagedDisk.DiskSizeGB –OsType $ManagedDisk.OsType | |
# Create a new managed disk in the target subscription from the copied disk | |
New-AzDisk –Disk $diskConfig –DiskName $ManagedDisk.TargetName –ResourceGroupName $targetResourceGroupName | |
# Clean up at the end | |
SourceSubscription | |
if ($ShutDownDirection -eq '7' -or !$ShutDownDirection) { # Yes = 6, No = 7 | |
Revoke-AzDiskAccess –ResourceGroupName $ManagedDisk.ResourceGroupName –DiskName $TempSourceDiskName | |
# Remove the TEMP managed disk | |
Remove-AzDisk –ResourceGroupName $ManagedDisk.ResourceGroupName –DiskName $TempSourceDiskName –Force | |
} | |
if ($ShutDownDirection -eq '6') { # Yes = 6, No = 7 | |
# Working with production source disks, don't remove them | |
Revoke-AzDiskAccess –ResourceGroupName $ManagedDisk.ResourceGroupName –DiskName $ManagedDisk.SourceName | |
} | |
TargetSubscription | |
Remove-AzStorageAccount –ResourceGroupName $TargetResourceGroupName –Name $StorageAccount.StorageAccountName –Force | |
} | |
} | |
#endregion | |
########################################################################################## | |
####################### Select Source Virtual Machine ############################ | |
########################################################################################## | |
#region Select Azure Source Virtual Machine | @marckean | |
cls | |
SourceSubscription | |
write-host –nonewline "`n`tIn subscription… " –ForegroundColor Yellow; ` | |
write-host –nonewline $SourceSubscription.Name`n –ForegroundColor Green; | |
write-host –nonewline "`n`tPlease choose a " –ForegroundColor Yellow; ` | |
write-host –nonewline "Virtual Machine " –ForegroundColor Green | |
start-sleep –seconds 1 | |
# Get Virtual Machines that contain Managed Disks only – either as an OS Disk or as a Data Disk | |
<#$VirtualMachines = Find-AzResource -ExpandProperties -ResourceType 'Microsoft.Compute/virtualMachines' | | |
? {$_.Properties.storageProfile.osDisk.managedDisk -or $_.Properties.storageProfile.dataDisks.managedDisk}#> | |
$VirtualMachines = Get-AzVM | ? {$_.storageProfile.osDisk.managedDisk -or $_.storageProfile.dataDisks.managedDisk} | select * | |
$SourceVM = ($VirtualMachines | Out-GridView –Title "Select a source Virtual Machine …" –PassThru) | |
#$SourceVM = Get-AzResource -ResourceGroupName $SourceVM.ResourceGroupName -ResourceType $SourceVM.Type -ApiVersion 2019-08-01 | select * -ExpandProperties | |
write-host –nonewline "`n`tYou selected this Virtual Machine: " –ForegroundColor Yellow; ` | |
write-host –nonewline $SourceVM.name`n –ForegroundColor Green; ` | |
start-sleep –seconds 3 | |
#endregion | |
########################################################################################## | |
######################## Virtual Machine Managed Disks ############################# | |
########################################################################################## | |
#region Virtual Machine Data Disks | @marckean | |
SourceSubscription | |
# Get any data disks associated with the source VM | |
$managedOSDiskname = $SourceVM.storageProfile.osDisk.name | |
#endregion | |
########################################################################################## | |
############################## Target Location ################################### | |
########################################################################################## | |
#region Virtual Machine Data Disks | @marckean | |
SourceSubscription | |
$locations = Get-AzLocation | |
$TargetLocation = ($locations | Out-GridView –Title "Choose a target location where to copy the managed disks to …" –PassThru).location | |
#endregion | |
########################################################################################## | |
############################ Target Resource Group ################################ | |
########################################################################################## | |
#region Target Azure Resource Group – Region and Resource Group creation | @marckean | |
######################## | Select Azure RM Resource Group | ####################### | @marckean | @marckean | |
TargetSubscription | |
cls | |
Write-Host "`n`tGathering a list of all Azure ARM Resource Groups Azure…" –ForegroundColor Cyan | |
$TargetResourcegroups = Get-AzResourceGroup | select ResourceGroupName, Location –ErrorAction SilentlyContinue | |
$TargetResourcegroups | ft | |
write-host –nonewline "Existing Resource Groups listed above (copy & paste) an existing one or enter a new Resource Group name: " ` | |
–ForegroundColor Green | |
$choice = read-host | |
$TargetResourceGroupName = $choice -replace "\s", "" | |
write-host –nonewline "`n`tThe Resource Group where new managed disk will be moved to: " –ForegroundColor Yellow; ` | |
write-host –nonewline $TargetResourceGroupName`n –ForegroundColor Green; ` | |
start-sleep –seconds 3 | |
####################### | Create the target Resource Group – if it doesn't exist | ####################### | @marckean | |
cls | |
Write-Host "`n`tCreating the target Resource group $TargetResourceGroupName (if it don't exist already)…" ` | |
–ForegroundColor Cyan | |
if (!(Get-AzResourceGroup –Name $TargetResourceGroupName –ErrorAction SilentlyContinue)) { | |
New-AzResourceGroup –Name $TargetResourceGroupName –Location $TargetLocation –Force | |
} | |
#endregion | |
########################################################################################## | |
################# Build the Managed Disk Object for use later ####################### | |
########################################################################################## | |
#region Build the Managed Disk Object for use later | |
SourceSubscription | |
#Get the source managed disks | |
$ManagedDisks = @() | |
$managedOSDisk = Get-AzDisk | ? {$_.Name -eq $managedOSDiskName} | |
# Data disks | |
foreach ($ManagedDisk in $SourceVM.storageProfile.dataDisks) { | |
$DataDisk = (Get-AzDisk | ? {$_.Name -eq $ManagedDisk.Name}) | |
$x = [PSCustomObject] @{ | |
SourceName = $ManagedDisk.Name | |
TargetName = '{0}{5}{4}{5}{1}{2}{5}{3}' -f 'Data', 'Lun', $ManagedDisk.lun, (Get-Date –Format yyyyMMdd), $SourceVM.Name, '_' | |
ResourceGroupName = $DataDisk.ResourceGroupName | |
Lun = $ManagedDisk.lun | |
Location = $DataDisk.location | |
Id = $DataDisk.id | |
AccountType = $DataDisk.Sku.Name | |
DiskSizeGB = $DataDisk.DiskSizeGB | |
DiskType = 'Data' | |
} | |
$ManagedDisks += $x | |
} | |
# OS disks | |
$x = [PSCustomObject] @{ | |
SourceName = $managedOSDisk.Name | |
TargetName = '{0}{3}{2}{3}{1}' -f 'OS', (Get-Date –Format yyyyMMdd), $SourceVM.Name, '_' | |
ResourceGroupName = $managedOSDisk.ResourceGroupName | |
Lun = $managedOSDisk.lun | |
Location = ($managedOSDisk).location | |
Id = ($managedOSDisk).id | |
AccountType = ($managedOSDisk).Sku.Name | |
DiskSizeGB = $managedOSDisk.diskSizeGB | |
DiskType = 'OS' | |
OsType = ($managedOSDisk).OsType | |
} | |
$ManagedDisks += $x | |
#endregion | |
########################################################################################## | |
############################# Shutdown Source VM ################################# | |
########################################################################################## | |
#region Shut-down source VM | @marckean | |
if ($ManagedDisks.disktype -contains 'Data') { | |
SourceSubscription | |
$ProvisioningState = (Get-AzVM –ResourceGroupName $SourceVM.ResourceGroupName –Name $SourceVM.Name –Status).Statuses.displaystatus | |
if ($ProvisioningState -notcontains 'VM deallocated') { | |
# Yes = 6, No = 7 | |
$ShutDownDirection = $wshell.Popup("As you have multiple disks, it's strongly suggested we shut-down the source VM?", 0, "Shutdown Direction", 48 + 4) | |
if ($ShutDownDirection -eq '6') { | |
cls | |
write-host –nonewline "`n`tShutting down… " –ForegroundColor Yellow; ` | |
write-host –nonewline $SourceVM.Name`n –ForegroundColor Green | |
start-sleep –seconds 1 | |
Stop-AzVM –Name $SourceVM.Name –ResourceGroupName $SourceVM.ResourceGroupName –Force | |
} | |
} | |
} | |
#endregion | |
########################################################################################## | |
########################################################################################## | |
########################################################################################## | |
########################################################################################## | |
########################################################################################## | |
########################################################################################## | |
########################################################################################## | |
########################################################################################## | |
################### The script does the work, grab a coffee ######################## | |
########################################################################################## | |
########################################################################################## | |
########################################################################################## | |
########################################################################################## | |
########################################################################################## | |
########################################################################################## | |
########################################################################################## | |
########################################################################################## | |
########################################################################################## | |
cls | |
Write-Host "`n`tThe script is doing the work, grab a coffee…" –ForegroundColor Cyan; | |
write-host –nonewline "`n`tCheck the target Resource Group shortly for the new copied Managed Disk…`n`n" ` | |
–ForegroundColor Yellow | |
########################################################################################## | |
################### Copy Managed Disk within the same Tenant ######################## | |
########################################################################################## | |
#region If the Source and Target user account is the same | |
if ($SourceTargetAccount -eq '6') { # Yes = 6, No = 7 | |
TargetSubscription | |
foreach ($ManagedDisk in $ManagedDisks) { | |
# In the same location | |
if ($ManagedDisk.Location -eq $TargetLocation) { | |
$diskConfig = New-AzDiskConfig –SourceResourceId $managedDisk.Id –Location $TargetLocation –CreateOption Copy | |
#Create a new managed disk in the target subscription and resource group | |
$TargetManagedDisk = New-AzDisk –Disk $diskConfig –DiskName $ManagedDisk.TargetName ` | |
–ResourceGroupName $targetResourceGroupName | |
} | |
# In different locations | |
if ($ManagedDisk.Location -ne $TargetLocation) { | |
MDtoSAStoMD | |
} | |
} | |
} | |
#endregion | |
########################################################################################## | |
####################### Copy Managed Disk Across Tenants ############################ | |
########################################################################################## | |
#region If the Source and Target user account is NOT the same | |
if ($SourceTargetAccount -eq '7') { # Yes = 6, No = 7 | |
foreach ($ManagedDisk in $ManagedDisks) { | |
MDtoSAStoMD | |
} | |
} | |
#endregion |
Good day , i was implementing your script and its throwing an error after copying some data as shown below
Copying the Managed Disk…
CopyId : 7c9c7632-c336-41e1-994c-d067860cff5f
CompletionTime : 3/17/2019 9:22:38 AM +00:00
Status : Failed
Source : https://md-nckrg2gdpq2t.blob.core.windows.net/vt3wbbdw02kf/abcd?sv=2017-04-17&sr=b&si=ffdeac3e-5976-44fd-ad59-1edfdd791742&si
g=ZYpAZpHPyL2XY9b4ybb%2BNbkUxwOKGhDHX6U3DOa8EhA%3D
BytesCopied : 81612800000
TotalBytes : 1098437886464
StatusDescription : 403 AuthenticationFailed “Copy failed when reading the source.”
DestinationSnapshotTime :
New-AzDisk : Cannot import source blob https://46944050949490.blob.core.windows.net/vhds/Data_QlikSenseProd_Lun0_20190317.vhd since it has not been
completely copied yet. Copy status of the blob is CopyFailed.
ErrorCode: BadRequest
ErrorMessage: Cannot import source blob https://46944050949490.blob.core.windows.net/vhds/Data_QlikSenseProd_Lun0_20190317.vhd since it has not been
completely copied yet. Copy status of the blob is CopyFailed.
ErrorTarget:
StatusCode: 400
ReasonPhrase: Bad Request
OperationID : 49581a14-aeed-4e70-8247-8ea454e0c571
At C:\Users\martin\Desktop\Untitled2.ps1:172 char:9
+ New-AzDisk -Disk $diskConfig -DiskName $ManagedDisk.TargetNam …
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : CloseError: (:) [New-AzDisk], ComputeCloudException
+ FullyQualifiedErrorId : Microsoft.Azure.Commands.Compute.Automation.NewAzureRmDisk
AZURE_USERNAME_HERE Microsoft Azure 82a44e23-540a-4a9c-a1b7-13cb490e80c8 AzureCloud
Name : 762a48b6-c0a4-44b6-860a-0f7799bbb925
StartTime : 3/17/2019 11:23:04 AM
EndTime : 3/17/2019 11:23:37 AM
Status : Succeeded
Error :
AZURE_USERNAME_HERE Microsoft Azure 82a44e23-540a-4a9c-a1b7-13cb490e80c8 AzureCloud
AZURE_USERNAME_HERE Microsoft Azure 82a44e23-540a-4a9c-a1b7-13cb490e80c8 AzureCloud
AZURE_USERNAME_HERE Microsoft Azure 82a44e23-540a-4a9c-a1b7-13cb490e80c8 AzureCloud
It’s the time it takes for the SAS URL to be alive for
ok maybe i’m slow, where is the script?
It’s there, hit refresh