Skip to content
Menu
Tech Automation Blog
  • About Author
  • Contact
Tech Automation Blog

Convert Azure Premium disk to Standard disk using Powershell

Posted on August 17, 2019February 27, 2022

Update : updated script to support Azure Az powershell module.

Azure Managed disk is Microsoft disk storage solution. With managed disks, all you have to do is provision the disk, and Azure takes care of the rest.

Microsoft provides different Managed disk types for different performance category/IOPS. Refer here for more information.

It is very common to deploy Azure VMs with Premium disk to get better performance. However, it is more expensive than a Standard disk.

If higher IOPS is not an absolute requirement, it is always better to provision VMs with Standard disk. However, sometimes we only realize once the VM is already running. Therefore, a script will be very handy to quickly convert Premium disk to Standard disk, specially, if we have a large number of VMs. Following script will help to quickly convert Premium disk to Standard disk in Azure or vice-a-versa.

Before start using this script, make sure, you have Azure Az Module installed and imported on the system. For more information on how to install and configure Az module refer following article : https://docs.microsoft.com/en-us/powershell/azure/new-azureps-module-az?view=azps-5.5.0

Set parameter values based on your requirements. Hope it helps!

Param(
    [Parameter(Mandatory=$true)]
    [string]$vmListPath,
    [Parameter(Mandatory=$false)]
    [string]$diskSku
)
$date = Get-Date -UFormat "%m-%d-%Y_%H%M%S"
$tFile = "$($env:TEMP)\DiskConversion_Transcript_$($date).txt"
$dFormat = "%m-%d-%Y %H:%M:%S"
Start-Transcript -Path $tFile -Append -NoClobber
# Target Disk SKU  - options - Standard_LRS and Premium_LRS based on requirements
$diskSku = 'Standard_LRS'
#
foreach($vm in Get-Content $vmListPath){
    Write-Host "[$(Get-Date -UFormat $dFormat)] INFORMATION: Script Execution Starts on VM $vm"  -ForegroundColor Green
    $vmDetails = $vmId = $osDiskName = $dataDisks = $vmName = $updateDisk = ""
    $vmName = $vm
    # Get VM Resource Details
    $vmInfo = Get-AzResource -Name $vmName -ResourceType Microsoft.Compute/virtualMachines
    $resourceGroupName = $vmInfo.ResourceGroupName
    
    # Stop and deallocate the VM before changing the size
    $vmPowerStatus = (Get-AzVM -Name $vmName -ResourceGroupName $resourceGroupName -Status).Statuses.code
    if($vmPowerStatus -contains "PowerState/running"){
        $vmRunning = $true
        #Write-Host "[$(Get-Date -UFormat $dFormat)] INFORMATION: VM is running, don't do anything on VM $vmName"  -ForegroundColor Green

        Write-Host "[$(Get-Date -UFormat $dFormat)] INFORMATION: VM is running, Deallocating $vmName"  -ForegroundColor Green
        $stopVM = Stop-AzVM -Name $vmName -ResourceGroupName $resourceGroupName -Force -Confirm:$false
        do
        {
            Start-Sleep -Seconds 5
            $vmPowerStatus = (Get-AzVM -Name $vmName -ResourceGroupName $resourceGroupName -Status).Statuses.code
        }while($vmPowerStatus -contains "PowerState/running")

        $allDisks = @()
        $vmDetails = Get-AzVM -Name $vmName -resourceGroupName $resourceGroupName
        $vmId = $vmDetails.Id
        $osDiskName = $vmDetails.StorageProfile.OsDisk.Name
        $allDisks += $osDiskName
        $dataDisks = $vmDetails.StorageProfile.DataDisks
        if([string]::IsNullOrEmpty($dataDisks)){
            Write-Host "[$(Get-Date -UFormat $dFormat)] INFORMATION: No Data disk attached to VM $vmName" -ForegroundColor Green
        }else{
            foreach($dataDisk in $dataDisks){
                $allDisks += $dataDisk.Name
            }
        }
        foreach($disk in $allDisks){
            $sku = $diskManagedBy = ""
            $vmDiskDetails = Get-AzDisk -Name $disk -ResourceGroupName $resourceGroupName
            if([string]::IsNullOrEmpty($vmDiskDetails)){
                Write-Host "[$(Get-Date -UFormat $dFormat)] ERROR: VM Disk not found - $disk" -ForegroundColor Red
            }else{
                $sku = $vmDiskDetails.Sku.Name
                $diskManagedBy = $vmDiskDetails.ManagedBy
                if($sku -eq 'Premium_LRS' -or $sku -eq 'StandardSSD_LRS'){
                    if($diskManagedBy -eq $vmId){
                        Write-Host "[$(Get-Date -UFormat $dFormat)] INFORMATION: Changing Disk sku for Disk $disk on VM $vmName" -ForegroundColor Green
                        $diskUpdateConfig = New-AzDiskUpdateConfig -SkuName $diskSku
                        $updateDisk = Update-AzDisk -DiskUpdate $diskUpdateConfig -ResourceGroupName $resourceGroupName -DiskName $disk
                    }else{
                        Write-Host "[$(Get-Date -UFormat $dFormat)] ERROR: Disk $disk not managed by VM $vmName" -ForegroundColor Red
                    }
                }else{
                    Write-Host "[$(Get-Date -UFormat $dFormat)] INFORMATION: VM Disk $disk is not Premium_LRS or StandardSSD_LRS.No action required." -ForegroundColor Green
                }
            }
        }

    }else{
        Write-Host "[$(Get-Date -UFormat $dFormat)] INFORMATION: VM is NOT running, Disk sku will be changed if sku is 'Premium_LRS' or 'StandardSSD_LRS' for VM $vmName"  -ForegroundColor Green
        $allDisks = @()
        $vmDetails = Get-AzVM -Name $vmName -resourceGroupName $resourceGroupName
        $vmId = $vmDetails.Id
        $osDiskName = $vmDetails.StorageProfile.OsDisk.Name
        $allDisks += $osDiskName
        $dataDisks = $vmDetails.StorageProfile.DataDisks
        if([string]::IsNullOrEmpty($dataDisks)){
            Write-Host "[$(Get-Date -UFormat $dFormat)] INORMATION: No Data disk attached to VM $vmName" -ForegroundColor Green
        }else{
            foreach($dataDisk in $dataDisks){
                $allDisks += $dataDisk.Name
            }
        }
        foreach($disk in $allDisks){
            $sku = $diskManagedBy = ""
            $vmDiskDetails = Get-AzDisk -Name $disk -ResourceGroupName $resourceGroupName
            if([string]::IsNullOrEmpty($vmDiskDetails)){
                Write-Host "[$(Get-Date -UFormat $dFormat)] ERROR: VM Disk not found - $disk" -ForegroundColor Red
            }else{
                $sku = $vmDiskDetails.Sku.Name
                $diskManagedBy = $vmDiskDetails.ManagedBy
                if($sku -eq 'Premium_LRS' -or $sku -eq 'StandardSSD_LRS'){
                    if($diskManagedBy -eq $vmId){
                        Write-Host "[$(Get-Date -UFormat $dFormat)] INFORMATION: Changing Disk sku for Disk $disk on VM $vmName" -ForegroundColor Green
                        $diskUpdateConfig = New-AzDiskUpdateConfig -SkuName $diskSku
                        $updateDisk = Update-AzDisk -DiskUpdate $diskUpdateConfig -ResourceGroupName $resourceGroupName -DiskName $disk
                    }else{
                        Write-Host "[$(Get-Date -UFormat $dFormat)] ERROR: Disk $disk not managed by VM $vmName" -ForegroundColor Red
                    }
                }else{
                    Write-Host "[$(Get-Date -UFormat $dFormat)] INFORMATION: VM Disk $disk is not Premium_LRS or StandardSSD_LRS.No action required." -ForegroundColor Green
                }
            }
        }
    }
    if($vmRunning){
        try{
            Write-Host "[$(Get-Date -UFormat $dFormat)] INFORMATION: Powering on Virtual Machine $vmName" -ForegroundColor Green
            $startVM = Start-AzVM -Name $vmName -ResourceGroupName $resourceGroupName -Confirm:$false
            do
            {
                Start-Sleep -Seconds 5
                $vmPowerStatus = (Get-AzVM -Name $vmName -ResourceGroupName $resourceGroupName -Status).Statuses.code
            }while(!($vmPowerStatus -contains "PowerState/running"))
            Write-Host "[$(Get-Date -UFormat $dFormat)] INFORMATION: Virtual Machine $vmName is back online now" -ForegroundColor Green
        }
        catch{
            Write-Host "[$(Get-Date -UFormat $dFormat)] ERROR: Failed to bring $vmName online.Please check the $vmName through portal." -ForegroundColor Red
        }
    }
    Write-Host "[$(Get-Date -UFormat $dFormat)] INFORMATION: Script Execution Ends on VM $vmName"  -ForegroundColor Green
    Write-Host (("=") * 100)
}
Stop-Transcript

Download above script and save it with a .ps1 file extension. Open powershell console and, login to your Azure account using – Login-AzAccount. It will prompt you to enter your Azure credentials.

This image has an empty alt attribute; its file name is image-3.png
Login to Azure account

Once you login to Azure, run the powershell script saved in previous step.

Run Powershell script

Provide the path to the file containing list of Azure VMs as below and press enter to tun the script.

Pass parameter

Share this:

  • Click to share on X (Opens in new window) X
  • Click to share on Facebook (Opens in new window) Facebook
  • Click to share on LinkedIn (Opens in new window) LinkedIn
June 2025
M T W T F S S
 1
2345678
9101112131415
16171819202122
23242526272829
30  
« May    

Recent Posts

  • Monitor and alert Azure Service Health issues May 5, 2020
  • AWS IAM User access review May 3, 2020
  • Integrate Azure Security Center with Event Hub April 28, 2020
  • Add Tags to Azure Subscription April 24, 2020
  • Automate Azure billing report in Excel March 6, 2020

Categories

©2025 Tech Automation Blog | Powered by SuperbThemes