aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnthony Wang2020-06-28 12:47:16 -0500
committerGitHub2020-06-28 12:47:16 -0500
commit1be51e1a7fce9a7fc567381f47abc1c7898f4e46 (patch)
tree9e53939a2b1695efbc9db034bed48a20a9a476ce
parentfd332f3d05f3309e0a2bc09fb2ed23ef15d00c78 (diff)
Create Shrink-AzDisk.ps1HEADmaster
-rw-r--r--Shrink-AzDisk.ps1166
1 files changed, 166 insertions, 0 deletions
diff --git a/Shrink-AzDisk.ps1 b/Shrink-AzDisk.ps1
new file mode 100644
index 0000000..4eaa3c2
--- /dev/null
+++ b/Shrink-AzDisk.ps1
@@ -0,0 +1,166 @@
+# Variables
+$DiskID = "/subscriptions/b1392e53-0162-4387-af15-dbf530c06f40/resourceGroups/TA180M/providers/Microsoft.Compute/disks/Windows10Pro_OsDisk_1_dfa2bffedea144c3901e9e4a3fadbbe3"
+$VMName = "Windows10Pro"
+$DiskSizeGB = 64
+$AzSubscription = "Azure for Students"
+
+# 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 from ID
+$Disk = Get-AzDisk | ? Id -eq $DiskID
+
+# Get VM/Disk generation from Disk
+$HyperVGen = $Disk.HyperVGeneration
+
+# Get Disk Name from Disk
+$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 = "shrink" + [system.guid]::NewGuid().tostring().replace('-','').substring(1,18)
+
+#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 `
+ -HyperVGeneration $HyperVGen
+
+$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"
+
+#Create the new disk with the same SKU as the current one
+$accountType = $Disk.Sku.Name
+
+# 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 -HyperVGeneration $HyperVGen
+
+#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