Created
June 12, 2019 20:42
-
-
Save pkhabazi/d0235a792445eb05b46cdf1433833d06 to your computer and use it in GitHub Desktop.
At the moment of writing this blog it’s unfortunately not possible to move an Azure VM with Managed disk to another Resource Group or to another Description. However, Microsoft says on the Azure Portal that this will be possible in the near feature. For the time being, I have chosen to write a small PowerShell script that will do the move fully …
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
<# | |
.Synopsis | |
Move Azure VM with Managed Disk to another Resource Group | |
.DESCRIPTION | |
Long description | |
.EXAMPLE | |
Example of how to use this cmdlet | |
.INPUTS | |
Inputs to this cmdlet (if any) | |
.OUTPUTS | |
Output from this cmdlet (if any) | |
.NOTES | |
FileName: MoveAzureVMWithManagedDisk.ps1 | |
Author: Pouyan Khabazi | |
Contact: @pkhabazi | |
Web: PKM-Technology.com | |
Created: 2017-10-17 | |
Updated: 2017-10-19 | |
Version: 1.0.1 | |
.COMPONENT | |
The component this cmdlet belongs to | |
.ROLE | |
The role this cmdlet belongs to | |
.FUNCTIONALITY | |
The functionality that best describes this cmdlet | |
#> | |
$wshell = New-Object -ComObject Wscript.Shell | |
#Login AzureRM | |
try { | |
Try { | |
Get-AzureRmSubscription -ErrorAction Continue | |
} | |
Catch { | |
if ($_ -like "*Login-AzureRmAccount to login*") { | |
Write-Host 'Start loging in Azure' -ForegroundColor Yellow | |
Login-AzureRmAccount | |
Write-Host 'Successfully logged id' -ForegroundColor Green | |
} | |
} | |
Write-Host 'Select Subscription' -ForegroundColor Yellow | |
Set-AzureRmContext -SubscriptionName $(if ((Get-AzureRmSubscription).count -gt '1') { ((Get-AzureRmSubscription).Name | Out-GridView -Title "Select Azure Subscription" -PassThru) } else {(Get-AzureRmSubscription).Name}) | |
Write-Host 'Subscription successfully selected' -ForegroundColor Green | |
} | |
catch { | |
Write-Host $_.Exception.Message | |
break | |
} | |
# Select Azure Resource Group and VM | |
try { | |
Write-Host 'Select Resource Group and VM' | |
$RgName = $((Get-AzureRmResourceGroup).ResourceGroupName | Out-GridView -Title "Select the Resource Group which contains the vm" -PassThru) | |
$VMName = if ((Get-AzureRmVM -ResourceGroupName $RgName -ErrorAction Continue).count -eq '0') {$wshell.Popup("No VM found in the current Resource Group", 0, "Error", 0x0); break} else {(Get-AzureRmVM -ResourceGroupName $RgName).Name | Out-GridView -Title "Select the VM you want to move" -PassThru} | |
$RgNameNew = $((Get-AzureRmResourceGroup).ResourceGroupName | Out-GridView -Title "Select the Resource Group where you want to move the VM to" -PassThru) | |
Write-Host 'Resources successfully selected' -ForegroundColor Green | |
} | |
catch { | |
Write-Host $_.Exception.Message | |
} | |
try { | |
Write-Host 'Start collecting VM Information' -ForegroundColor Yellow | |
## Collect Information for redeploying the VM | |
$vmConfigExisting = Get-AzureRmvm -VMName $vmName -ResourceGroupName $RgName | |
$NetworkInterface = Get-AzureRmNetworkInterface | Where-Object {$_.VirtualMachine -ne $null} | Where-Object {$_.VirtualMachine.Id -eq $vmConfigExisting.Id} | |
$vmStatus = (Get-AzureRmvm -VMName $vmName -ResourceGroupName $RgName -Status).statuses[1].DisplayStatus | |
## VM Info | |
$location = $vmConfigExisting.Location | |
$NickName = ($NetworkInterface.Id).Split('/')| Select-Object -Last 1 | |
$NickId = $vmConfigExisting.NetworkProfile.NetworkInterfaces.id | |
$osDiskName = $vmConfigExisting.StorageProfile.OsDisk.Name | |
$VMSize = $vmConfigExisting.HardwareProfile.VmSize | |
$IPaddress = $NetworkInterface.IpConfigurations.PrivateIpAddress | |
$subnet = $NetworkInterface.IpConfigurations.Subnet.Id | |
## Snapshot and Storage variables | |
$StorageAccountName = "tempmigstor$(Get-Date -Format sMmmshh)" | |
$storageAccountType = "Standard_LRS" | |
$snapshotName = $VMName + "-Snapshot" | |
$destContainer = "vhds" | |
$blobName = $snapshotName + ".vhd" | |
$osDiskUri = "https://$StorageAccountName.blob.core.windows.net/$destContainer/$blobName" | |
Write-Host "Successfully collectted all the information" -ForegroundColor Green | |
} | |
catch { | |
Write-Host $_.Exception.Message | |
break | |
} | |
function Create-Snapshot { | |
try { | |
## Shutdown VM before making Snapshot | |
if ($vmStatus -like "VM running") { | |
Write-Host 'VM is running, stopping VM..' -ForegroundColor Yellow | |
Stop-AzureRmVM -Name $VMName -ResourceGroupName $RgName -Force | |
Write-Host 'VM successfully stopped' -ForegroundColor Green | |
} | |
### Create Snapshot | |
try { | |
Write-Host 'Start creating snapshot' -ForegroundColor Yellow | |
$Disk = Get-AzureRmDisk -ResourceGroupName $RgName -DiskName $($vmConfigExisting.StorageProfile.OsDisk.Name) | |
$storageAccountType = $Disk.AccountType | |
$Snapshot = New-AzureRmSnapshotConfig -SourceUri $Disk.Id -CreateOption Copy -Location $location | |
New-AzureRmSnapshot -Snapshot $Snapshot -SnapshotName $snapshotName -ResourceGroupName $RgNameNew | |
$absoluteUri = (Grant-AzureRmSnapshotAccess -ResourceGroupName $RgNameNew -SnapshotName $snapshotName -Access 'Read' -DurationInSecond 3600).AccessSAS | |
Write-Host 'Snapshot successfully created' -ForegroundColor Green | |
} | |
catch { | |
Write-Host $_.Exception.Message | |
break | |
} | |
### Create Storage Account if not exist | |
try { | |
if (Get-AzureRmStorageAccount -ResourceGroupName $RgNameNew -Name $StorageAccountName -ErrorAction SilentlyContinue) { | |
Write-Host "Storage Account Exist" -ForegroundColor Green | |
$ctx = (Get-AzureRmStorageAccount -ResourceGroupName $RgNameNew -Name $StorageAccountName).Context | |
} | |
else { | |
Write-Host "Storage Account doesnt't exist and will be created!" -ForegroundColor Yellow | |
$NewStoragAccount = New-AzureRmStorageAccount -ResourceGroupName $RgNameNew -Name $StorageAccountName -Location $location -SkuName "Standard_LRS" -ErrorAction Stop | |
$ctx = $NewStoragAccount.Context | |
Write-Host 'Storage Account successfully created' -ForegroundColor Green | |
} | |
} | |
catch { | |
Write-Host $_.Exception.Message | |
break | |
} | |
### Copy Snapshot to Azure Blob | |
Write-Host 'start copying snapshot to Azure Blob' -ForegroundColor Yellow | |
if (! (Get-AzureStorageContainer -Name $destContainer -Context $ctx -ErrorAction SilentlyContinue)) { | |
New-AzureStorageContainer -Name $destContainer -Context $ctx -Permission blob -ErrorAction SilentlyContinue | |
} | |
$destContext = New-AzureStorageContext -StorageAccountName $storageAccountName -StorageAccountKey ((Get-AzureRmStorageAccountKey -ResourceGroupName $RgNameNew -Name $StorageAccountName)[0].Value) | |
Start-AzureStorageBlobCopy -AbsoluteUri $absoluteUri -DestContainer $destContainer -DestContext $destContext -DestBlob $blobName | |
$CopyStatus = Get-AzureStorageBlobCopyState -Blob $blobName -Container $destContainer -Context $ctx | |
while ($CopyStatus.status -like 'Pending') { | |
try { | |
$CopyStatus = Get-AzureStorageBlobCopyState -Blob $blobName -Container $destContainer -Context $ctx | |
Start-Sleep -Seconds 30 | |
} | |
catch { | |
Write-Host $_.Exception.Message | |
} | |
} | |
Write-Host 'Succesvoll copied content to Azure Blob' -ForegroundColor Green | |
} | |
catch { | |
Write-Host $_.Exception.Message | |
} | |
} | |
function Create-NewAzureRMVM { | |
try { | |
Write-Host 'Start removing VM' -ForegroundColor Yellow | |
Remove-AzureRmVM -Name $VMName -Force -ResourceGroupName $RgName | |
Remove-AzureRmNetworkInterface -Name $NickName -ResourceGroupName $RgName -Force | |
Remove-AzureRmDisk -ResourceGroupName $RgName -DiskName $osDiskName -Force | |
Write-Host 'VM successfully removed' -ForegroundColor Green | |
} | |
catch { | |
Write-Host $_.Exception.Message | |
} | |
Try { | |
Write-Host 'Start creating VM' -ForegroundColor Yellow | |
$IPconfig = New-AzureRmNetworkInterfaceIpConfig -Name 'IPConfig1' -PrivateIpAddressVersion 'IPv4' -PrivateIpAddress $IPaddress -SubnetId $subnet | |
$nic = New-AzureRmNetworkInterface -Name $NickName -ResourceGroupName $RgNameNew -Location $location -IpConfiguration $IPconfig -Confirm:$false -Force | |
$vmConfig = New-AzureRmVMConfig -VMName $vmName -VMSize $VMSize | |
$vm = Add-AzureRmVMNetworkInterface -VM $vmConfig -Id $nic.Id | |
$osDisk = New-AzureRmDisk -DiskName $osDiskName -Disk (New-AzureRmDiskConfig -AccountType $storageAccountType -Location $location -CreateOption Import -SourceUri $osDiskUri) -ResourceGroupName $RgNameNew | |
$vm = Set-AzureRmVMOSDisk -VM $vm -ManagedDiskId $osDisk.Id -StorageAccountType $storageAccountType -DiskSizeInGB $($vmConfigExisting.StorageProfile.OsDisk.DiskSizeGB) -CreateOption Attach -Windows | |
$vm = Set-AzureRmVMBootDiagnostics -VM $vm -disable | |
#Create the new VM | |
New-AzureRmVM -ResourceGroupName $RgNameNew -Location $location -VM $vm | |
Write-Host 'VM successfully created' -ForegroundColor Green | |
} | |
catch { | |
Write-Host $_.Exception.Message | |
} | |
} | |
function Clean-Migration { | |
$clean = $($wshell.Popup("Operation Completed, do you want to clean the snapshot", 0, "Done", 0x4)) | |
if ($clean -eq '6') { | |
Write-Host 'Start Cleaning' -ForegroundColor Yellow | |
try { | |
Remove-AzureRmStorageAccount -ResourceGroupName $RgNameNew -Name $StorageAccountName -Force | |
Write-Host 'Azure Storage Accpunt successfully removed' -ForegroundColor Green | |
Revoke-AzureRmSnapshotAccess -ResourceGroupNam $RgNameNew -SnapshotName $snapshotName | |
Write-Host 'Snapshot Acces key successfully revoked' -ForegroundColor Green | |
Remove-AzureRmSnapshot -ResourceGroupName $RgNameNew -SnapshotName $snapshotName -Force | |
Write-Host 'Azure Snapshhot successfully removed' -ForegroundColor Green | |
} | |
catch { | |
Write-Host $_.Exception.Message | |
} | |
} | |
else { | |
Write-Host 'No Cleaning' -ForegroundColor Gray | |
} | |
} | |
Create-Snapshot | |
Create-NewAzureRMVM | |
Clean-Migration |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment