Azure Managed VM Images - Using Premium Data Disks

Azure Managed VM Images provide a great way to capture customizations to a base Virtual Machine that can be reused over-and-over as a custom image - and these images can include the Managed Disks for both OS and data disks! However, when saving an image, disks are defaulted to using Standard storage to save on costs.  When provisioning a new VM from this image via the portal or PowerShell, we can override this default to use Premium storage for OS disks but not currently for data disks.

Premium data disks with Managed VM Images ... What to do, what to do?!

So, how can we use Managed VM Images to provision new VMs with Premium data disks? Well ...we can provision the new VMs using ARM templates (see template storageProfile snippet here) instead of via the Portal or PowerShell, or we can use a bit of PowerShell magic to convert our existing Managed VM Image(s) to default to Premium Storage. Below, I've included a sample script snippet that we can leverage to convert an existing Managed VM Image to a new image that defaults the disks to using Premium storage.  You can also fork a copy of this script from my GitHub repo here.

 1:  #-------------------------------------------------------------------------  
2:  # Copyright (c) Microsoft. All rights reserved.  
3:  #  
4:  # Licensed under the Apache License, Version 2.0 (the "License");  
5:  # you may not use this file except in compliance with the License.  
6:  # You may obtain a copy of the License at  
7:  #  https://www.apache.org/licenses/LICENSE-2.0  
8:  #  
9:  # Unless required by applicable law or agreed to in writing, software  
10:  # distributed under the License is distributed on an "AS IS" BASIS,  
11:  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  
12:  # See the License for the specific language governing permissions and  
13:  # limitations under the License.  
14:  #--------------------------------------------------------------------------  
15:    
16:  # Sign-in with Azure AD account  
17:    
18:    $Error.Clear()  
19:    
20:    Login-AzureRmAccount  
21:    
22:  # Select Azure Subscription  
23:    
24:    $subscriptionId =   
25:      ( Get-AzureRmSubscription |  
26:        Out-GridView `  
27:         -Title "Select an Azure Subscription ..." `  
28:         -PassThru  
29:      ).SubscriptionId  
30:    
31:    Select-AzureRmSubscription `  
32:      -SubscriptionId $subscriptionId  
33:    
34:  # Select Azure Resource Group in which existing VM is provisioned  
35:    
36:    $rgName =  
37:      ( Get-AzureRmResourceGroup |  
38:        Out-GridView `  
39:         -Title "Select Azure Resource Group in which VM is provisioned ..." `  
40:         -PassThru  
41:      ).ResourceGroupName  
42:    
43:  # Select Managed VM Image to convert to Premium storage disks  
44:    
45:    $imageName =   
46:      ( Get-AzureRmImage `  
47:        -ResourceGroupName $rgName   
48:      ).Name |   
49:      Out-GridView `  
50:        -Title "Select an existing Image to convert ..." `  
51:        -PassThru  
52:    
53:    $image =   
54:      Get-AzureRmImage `  
55:        -ResourceGroupName $rgName `  
56:        -Name $imageName  
57:    
58:    $location =   
59:      $image.Location  
60:    
61:  # Convert OS disk to default to Premium storage  
62:    
63:    $osDisk =   
64:      $image.StorageProfile.OsDisk  
65:    
66:    $osDisk.StorageAccountType =   
67:      "PremiumLRS"  
68:    
69:  # Convert Data disks to default to Premium Storage  
70:    
71:    $dataDisks =   
72:      $image.StorageProfile.DataDisks  
73:    
74:    for ($i = 0; $i -lt $dataDisks.Count; $i++)  
75:    {   
76:      $dataDisks[$i].StorageAccountType = "PremiumLRS"   
77:    }  
78:    
79:  # Enter new name for converted image  
80:    
81:    $newImageName =   
82:      Read-Host `  
83:        -Prompt "Enter new name for converted VM image [Enter = ${imageName}-ssd]"  
84:    
85:    if ($newImageName -eq "")   
86:    {  
87:      $newImageName = "${imageName}-ssd"   
88:    }  
89:    
90:  # Define new config for converted image  
91:    
92:    $newImageConfig =   
93:      New-AzureRmImageConfig `  
94:        -Location $location `  
95:        -OsDisk $osDisk `  
96:        -DataDisk $dataDisks  
97:    
98:  # Create new image based on converted image config   
99:    
100:    New-AzureRmImage `  
101:      -ResourceGroupName $rgName `  
102:      -ImageName $newImageName `  
103:      -Image $newImageConfig  
104: