Created
March 22, 2020 18:09
-
-
Save Anduin2017/d2c81af000fa70a7f7c021eebe935c2f to your computer and use it in GitHub Desktop.
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
# Variables | |
$DiskID = "/subscriptions/e82a2bbd-7d7c-4fa7-ad47-bc0feef07aa1/resourceGroups/Anduin/providers/Microsoft.Compute/disks/StarDiskWithOS"# eg. "/subscriptions/203bdbf0-69bd-1a12-a894-a826cf0a34c8/resourcegroups/rg-server1-prod-1/providers/Microsoft.Compute/disks/Server1-Server1" | |
$VMName = "StarX" | |
$DiskSizeGB = 90 | |
$AzSubscription = "Visual Studio Enterprise – MPN" | |
# Script | |
# Provide your Azure admin credentials | |
Connect-AzAccount | |
#Provide the subscription Id of the subscription where snapshot is created | |
Select-AzSubscription -Subscription $AzSubscription | |
# VM to resize disk of | |
$VM = Get-AzVm | ? Name -eq $VMName | |
#Provide the name of your resource group where snapshot is created | |
$resourceGroupName = $VM.ResourceGroupName | |
# Get Disk Name from ID | |
$Disk = Get-AzDisk | ? Id -eq $DiskID | |
$DiskName = $Disk.Name | |
# Get SAS URI for the Managed disk | |
$SAS = Grant-AzDiskAccess -ResourceGroupName $resourceGroupName -DiskName $DiskName -Access 'Read' -DurationInSecond 600000; | |
#Provide the managed disk name | |
#$managedDiskName = "yourManagedDiskName" | |
#Provide Shared Access Signature (SAS) expiry duration in seconds e.g. 3600. | |
#$sasExpiryDuration = "3600" | |
#Provide storage account name where you want to copy the snapshot - the script will create a new one temporarily | |
$storageAccountName = "sashrinkddisk" + ($($VMName -replace '[^a-zA-Z0-9]', '')).ToLower() | |
#Name of the storage container where the downloaded snapshot will be stored | |
$storageContainerName = $storageAccountName | |
#Provide the key of the storage account where you want to copy snapshot. | |
#$storageAccountKey = "yourStorageAccountKey" | |
#Provide the name of the VHD file to which snapshot will be copied. | |
$destinationVHDFileName = "$($VM.StorageProfile.OsDisk.Name).vhd" | |
#Generate the SAS for the managed disk | |
#$sas = Grant-AzureRmDiskAccess -ResourceGroupName $resourceGroupName -DiskName $managedDiskName -Access Read -DurationInSecond $sasExpiryDuration | |
#Create the context for the storage account which will be used to copy snapshot to the storage account | |
$StorageAccount = New-AzStorageAccount -ResourceGroupName $resourceGroupName -Name $storageAccountName -SkuName Standard_LRS -Location $VM.Location | |
$destinationContext = $StorageAccount.Context | |
$container = New-AzStorageContainer -Name $storageContainerName -Permission Off -Context $destinationContext | |
#Copy the snapshot to the storage account and wait for it to complete | |
Start-AzStorageBlobCopy -AbsoluteUri $SAS.AccessSAS -DestContainer $storageContainerName -DestBlob $destinationVHDFileName -DestContext $destinationContext | |
while(($state = Get-AzStorageBlobCopyState -Context $destinationContext -Blob $destinationVHDFileName -Container $storageContainerName).Status -ne "Success") { $state; Start-Sleep -Seconds 20 } | |
$state | |
# Revoke SAS token | |
Revoke-AzDiskAccess -ResourceGroupName $resourceGroupName -DiskName $DiskName | |
# Emtpy disk to get footer from | |
$emptydiskforfootername = "$($VM.StorageProfile.OsDisk.Name)-empty.vhd" | |
# Empty disk URI | |
#$EmptyDiskURI = $container.CloudBlobContainer.Uri.AbsoluteUri + "/" + $emptydiskforfooter | |
$diskConfig = New-AzDiskConfig ` | |
-Location $VM.Location ` | |
-CreateOption Empty ` | |
-DiskSizeGB $DiskSizeGB | |
$dataDisk = New-AzDisk ` | |
-ResourceGroupName $resourceGroupName ` | |
-DiskName $emptydiskforfootername ` | |
-Disk $diskConfig | |
$VM = Add-AzVMDataDisk ` | |
-VM $VM ` | |
-Name $emptydiskforfootername ` | |
-CreateOption Attach ` | |
-ManagedDiskId $dataDisk.Id ` | |
-Lun 63 | |
Update-AzVM -ResourceGroupName $resourceGroupName -VM $VM | |
$VM | Stop-AzVM -Force | |
# Get SAS token for the empty disk | |
$SAS = Grant-AzDiskAccess -ResourceGroupName $resourceGroupName -DiskName $emptydiskforfootername -Access 'Read' -DurationInSecond 600000; | |
# Copy the empty disk to blob storage | |
Start-AzStorageBlobCopy -AbsoluteUri $SAS.AccessSAS -DestContainer $storageContainerName -DestBlob $emptydiskforfootername -DestContext $destinationContext | |
while(($state = Get-AzStorageBlobCopyState -Context $destinationContext -Blob $emptydiskforfootername -Container $storageContainerName).Status -ne "Success") { $state; Start-Sleep -Seconds 20 } | |
$state | |
# Revoke SAS token | |
Revoke-AzDiskAccess -ResourceGroupName $resourceGroupName -DiskName $emptydiskforfootername | |
# Remove temp empty disk | |
Remove-AzVMDataDisk -VM $VM -DataDiskNames $emptydiskforfootername | |
Update-AzVM -ResourceGroupName $resourceGroupName -VM $VM | |
# Delete temp disk | |
Remove-AzDisk -ResourceGroupName $resourceGroupName -DiskName $emptydiskforfootername -Force; | |
# Get the blobs | |
$emptyDiskblob = Get-AzStorageBlob -Context $destinationContext -Container $storageContainerName -Blob $emptydiskforfootername | |
$osdisk = Get-AzStorageBlob -Context $destinationContext -Container $storageContainerName -Blob $destinationVHDFileName | |
$footer = New-Object -TypeName byte[] -ArgumentList 512 | |
write-output "Get footer of empty disk" | |
$downloaded = $emptyDiskblob.ICloudBlob.DownloadRangeToByteArray($footer, 0, $emptyDiskblob.Length - 512, 512) | |
$osDisk.ICloudBlob.Resize($emptyDiskblob.Length) | |
$footerStream = New-Object -TypeName System.IO.MemoryStream -ArgumentList (,$footer) | |
write-output "Write footer of empty disk to OSDisk" | |
$osDisk.ICloudBlob.WritePages($footerStream, $emptyDiskblob.Length - 512) | |
Write-Output -InputObject "Removing empty disk blobs" | |
$emptyDiskblob | Remove-AzStorageBlob -Force | |
#Provide the name of the Managed Disk | |
$NewDiskName = "$DiskName" + "-new" | |
#Provide the storage type for the Managed Disk. PremiumLRS or StandardLRS. | |
$accountType = "Premium_LRS" | |
# Get the new disk URI | |
$vhdUri = $osdisk.ICloudBlob.Uri.AbsoluteUri | |
# Specify the disk options | |
$diskConfig = New-AzDiskConfig -AccountType $accountType -Location $VM.location -DiskSizeGB $DiskSizeGB -SourceUri $vhdUri -CreateOption Import -StorageAccountId $StorageAccount.Id | |
#Create Managed disk | |
$NewManagedDisk = New-AzDisk -DiskName $NewDiskName -Disk $diskConfig -ResourceGroupName $resourceGroupName | |
$VM | Stop-AzVM -Force | |
# Set the VM configuration to point to the new disk | |
Set-AzVMOSDisk -VM $VM -ManagedDiskId $NewManagedDisk.Id -Name $NewManagedDisk.Name | |
# Update the VM with the new OS disk | |
Update-AzVM -ResourceGroupName $resourceGroupName -VM $VM | |
$VM | Start-AzVM | |
start-sleep 180 | |
# Please check the VM is running before proceeding with the below tidy-up steps | |
# Delete old Managed Disk | |
Remove-AzDisk -ResourceGroupName $resourceGroupName -DiskName $DiskName -Force; | |
# Delete old blob storage | |
$osdisk | Remove-AzStorageBlob -Force | |
# Delete temp storage account | |
$StorageAccount | Remove-AzStorageAccount -Force |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment