- Reading Azure VM name, IP address, and hostname with PowerShell - Fri, Jul 28 2017
- Automating WSUS with PowerShell - Thu, Jul 13 2017
- Disable SSL and TLS 1.0/1.1 on IIS with PowerShell - Tue, Jun 27 2017
Have a look at the entire PowerShell script first:
$subscriptionID = "your_subscription_ID" $size = "10" # size in GB Select-AzureSubscription -SubscriptionId $subscriptionID Import-CSV -Path "C:\temp\vms_increase.csv" | %{ $svc = $_.cloudservice $nameVM= $_.name $vm=Get-AzureVM -ServiceName $svc -Name $nameVM write-host "---------------------------------------------" write-host "Create new data drive for $nameVM" $disk =$vm | Get-AzureDataDisk $luns=$disk.lun $lun= ($luns | Measure -Maximum).Maximum + 1 $label = $nameVM + "-DATA-LUN"+$lun $vhd = $nameVM + "-DATA-LUN"+$lun + ".vhd" $path="http://" + ($vm | Get-AzureOSDisk).MediaLink.Host + "/vhds/" + $vhd $vm | Add-AzureDataDisk -CreateNew -DiskSizeInGB $size -DiskLabel $label -HostCaching None -LUN $lun -MediaLocation $path | Update-AzureVM }
The first two lines just assign the Azure subscription ID to the $subscriptionID variable and the size of the new data drives to the $size variable. I am creating drives of the same size for each VM, but if you need them to be different sizes, you can just add one more column to the .csv file you'll see below. This contains the cloud service names and VM names; just put the drive size you'd like to assign to each VM in the new column.
I have to select my Azure subscription in the next line because I have multiple Azure subscriptions. If you have just one, you can comment out this line.
Next, I'm importing the CSV file with the Azure cloud service names and VM names. I then iterate through the names using the ForEach-Object cmdlet (% for short). The screenshot below shows my sample CSV file:
Then I'm getting the current values for the cloud service name and VM name from the CSV file into the $svc and $nameVM variables respectfully. I'm also storing the Azure VM name in the $vm variable using the Get-AzureVM cmdlet against the VM and service name I just got from the file. The next two lines just update the console, so I can see which VM I'm currently working on.
After doing this and before assigning any new drives to the VMs, I need to know if any data drives are already there. This is required because I need to know the LUN (logical unit number) where I'm going to assign the new drive. And to figure out which LUNs are available, I'm piping the $vm variable to the Get-AzureDataDisk cmdlet.
I store the result of this operation to the $disk variable to get all LUNs in the next line. And since my new LUN should be the next after the last one assigned, I'm piping the $luns variable to the Measure cmdlet to find the highest number. Then I just add one to that number.
Next, I have to determine the label, name, and path for the new drive. The label is simple: I just take the VM name and then add "-DATA-LUN" and the LUN number to it. The name ($vhd variable) is almost the same; I just add the .vhd extension at the end. Finally, I construct the path using "http://" as the prefix followed by the storage account name. I get this from the $vm variable (using the Get-AzureOsDisk cmdlet), the container name (which is "vhds" for my VMs), and the VHD (virtual hard disk) name.
Since all required information is now in place, I'm using it to add a new data drive to the VM, piping in the $vm variable to the Add-AzureDataDisk cmdlet and then piping out the result to the Update-AzureVM cmdlet.
This is how it looks from the PowerShell console:
Subscribe to 4sysops newsletter!
As you can see, this was a fairly simple task. In my view, it's a lot easier than initializing those drives on a Windows VM, formatting the drives, and then assigning drive letters. This is particularly true if you are working with many VMs. This will be the topic of my next article.