Summary: Use the Azure Resource Manager cmdlets to define the operating system disk on a storage blob for a virtual machine.
Would you help me, please? I need to know how to define storage for my virtual machine in Azure Resource Manager by using PowerShell.
Honorary Scripting Guy, Sean Kearney, is here as we happily go along our scripting way in Azure Resource Manager. Yesterday, we started the process by defining a virtual machine (VM) configuration. Today, we’ll set up the needed storage for this machine.
The cmdlet in charge of all of this is Set-AzureRMVMOSDisk. It’s called that because there is actually one to define a data disk, too. This is incredibly important when you define a virtual machine because it does help you define the roles in advance.
As an example, it’s always a good practice to separate your data from the operating system. Data will have different needs. Perhaps data needs more speed on far more expensive disks. Perhaps data is not critical, for example, when you’re using a ripper to convert raw data for graphics conversions. After the files are done, you don’t need to retain the temporary data.
In either case, we need to define the disks that are being attached and, ideally, their purpose.
To define a basic operating system disk, we need to provide three parameters:
- a filename
- the type of caching that it will need
- the storage blob to store it on
The file name is pretty easy, of course. You should choose a name that’s unique to the VM so that you don’t clash with other VHD files. You should also consider the possibility that the name that you choose might have been used before. (What? Nobody ever called a VM “Test”?)
To have a simple method to avoid a clash with other files, why not add some details to the file name that should make it a bit more unique, such as:
- Your initials
- A department code
- Today’s date and time
- The purpose of the disk (operating system or data)
- The VM name
I’m not suggesting all of these, but in today’s example, we’ll use at least the machine name and our initials to start and follow that by adding the type of disk (operating system or data).
If you remember from yesterday, we defined the VM name in the following manner:
$VMName=’HSG-Server1’
From this point, let’s identify our initials and the type of disk, and build out the file name:
$Initials=’HSG’
$Disk=’OS’
$Diskname=$VMName+’_’+’$Initials+’_’+$Disk
We next need to define the caching option for this disk. If you remember, when we grabbed the VM object from last week, we used it to obtain information that we needed.
The easiest way that I’ve found to get the type of caching for the disk is to reference one from a previous VM. This is stored under the StorageProfile property. You can access it in the following manner, and we’ll use last week’s VM as the example:
$VM=Get-AzureRMVM –name HSG-Linux1 –ResourceGroupName HSG-AzureRG
$VM.StorageProfile.OSDisk.Caching
As last week, we can pipe that into the clipboard or copy / paste the information or just type it:
$Caching = 'ReadWrite'
Our next challenge is to actually put this into the storage blob in question. If you wanted to use an existing blob that another VM was on, we would use last week’s technique by scooping the name from the original VM object:
$VM.StorageProfile.OSDisk.vhd.uri
From that point, you could do a little splitting and substring manipulation. The other approach is to identify a storage blob that you’d like to use with the Get-AzureRMStorageAccount cmdlet. We can list all available storage accounts by just running this cmdlet.
If you’d like to show only the ones that are available for a particular resource group, you can supply the particular resource group as a parameter:
Get-AzureRMStorageAccount –ResourceGroupName HSG-AzureRG
Now, if you need to filter on this because you could have multiple accounts, you’ll need to run this through a Where-Object. We can filter on the StorageAccountName property. In the following example, we are looking for storage accounts with the letters, hsg, in the name:
Get-AzureRmStorageAccount -ResourceGroupName HSG-AzureRG | Where { $_.StorageAccountName -match 'hsg' }
After we have a storage account object, we need to grab the blob URI from it. This is a part of the PrimaryEndpoints property, which we can access in the following manner:
$Storage=Get-AzureRmStorageAccount -ResourceGroupName HSG-AzureRG | Where { $_.StorageAccountName -match 'hsg' }
$StorageGroupURL=$Storage.PrimaryEndpoints.Blob+’/vhds/’
You’ll notice that we added ‘vhds’ to the name. That’s because, when we create a VM, it’s where Azure Resource Manager expects the data to be. In this manner, it matches the source URI from last week.
We now pull all the pieces together and assemble the object for the disk. Just as yesterday, it doesn’t actually do anything to Azure yet. We’re just building an object that will be used to eventually attach to a cmdlet to spin up the VM:
$DiskURI=$StorageAccountURL+$DiskName+’.vhd’
$AzureVM = Set-AzureRmVMOSDisk -VM $AzureVM -VhdUri $DiskURI -name $DiskName -CreateOption fromImage -Caching $Caching
At this point, the next part of the journey has been completed. Tomorrow, we start wiring up a network card, virtual, of course, on this machine.
I invite you to follow the Scripting Guys on Twitter and Facebook. If you have any questions, send email to them at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow.
Until then, always remember that with Great PowerShell comes Great Responsibility.
Sean Kearney
Honorary Scripting Guy
Cloud and Datacenter Management MVP