Azure 上面起一個 Windows VM 的 OS Disk 預設是 127GB
但通常用不到那麼大卻要負擔那麼多的租金
在以下網址找到可以縮小 OS Disk 的 PowerShell Script
https://github.com/jrudlin/Azure/blob/master/General/Shrink-AzDisk.ps1
需要注意 Script 的預設情況 Disk 是 沒有設置 Available Zone 的
以下 Script 已經將 Disk 的 Available Zone 加入避免錯誤
===== Script Start =====
# https://github.com/jrudlin/Azure/blob/master/General/Shrink-AzDisk.ps1 # Variables $DiskID = ""# eg. "/subscriptions/203bdbf0-69bd-1a12-a894-a826cf0a34c8/resourcegroups/rg-server1-prod-1/providers/Microsoft.Compute/disks/Server1-Server1" $VMName = "ShrinkDisk" $DiskSizeGB = 32 $AzSubscription = "Subscription Name" # 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 ` -Zone $Disk.Zones ` -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" + "-shrink" #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 ` -Zone $Disk.Zones ` -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
沒有留言:
張貼留言