Using PowerShell Remoting for disk provisioning automation
Windows Azure PowerShell cmdlets allow you to automate the construction of your infrastructure, typically creating and starting VMs, and attaching additional disks to expand the default storage configuration. This articles show a little recipe to also use Remote PowerShell to create and format a striped volume in the same script.
Attaching disks
The first thing to do is to attach some new disks to the virtual machine. I will not detail the process here as it is well documented elsewhere. Here is one way to do it:
Get-AzureVM -ServiceName $sn -Name $n | Add-AzureDataDisk -CreateNew -DiskSizeInGB 128 -DiskLabel "DataDisk0" -LUN 1 | Add-AzureDataDisk -CreateNew -DiskSizeInGB 128 -DiskLabel "DataDisk1" -LUN 2 | Update-AzureVM
This will create two new raw devices in your virtual machine.
Remote PowerShell
We are going to use PowerShell remoting to run scripts on a Virtual Machine without having to connect using Remote Desktop. You can read a complete overview of Remote PowerShell on Scripting Guy's blog for example, but here is what we need to use in a nutshell:
First, we need to retrieve the WinRM URI that will be used to connect to the remote VM:
$uri = Get-AzureWinRMUri -ServiceName $sn -Name $n
Then we need to construction a PowerShell session option object to work around those pesky security restrictions... Of course I wouldn't advise doing this in production, and read up on how to install the correct certificates.
$option = New-PSSessionOption -SkipCACheck -SkipCNCheck
And finally we need to collect some credentials, this command will open a UI prompt for you to type in a username and password.
$cred = Get-Credential
Using these variables, we should be able to start an interactive PowerShell session on the remote host:
Enter-PSSession -ConnectionUri $uri -SessionOption $option -Credential $cred
Later, we will use Invoke-Command
to run a script remotely.
Using DISKPART
You can feed DISKPART a text file containing the commands to run. Here is what you typically need to do to create a striped volume using the two disks we just attached. The disk and volume indices are hard-coded, so make sure to change them if your disk configuration differs from the Windows Azure standard! The indices below are based on the standard VM configuration of one persistent disk on C: and one temporary, local disk on D:.
select disk 2
clean
convert dynamic
select disk 3
clean
convert dynamic
create volume stripe disk=2,3
select volume 2
assign letter=E
format fs=ntfs quick
Putting it all together
Now we can assemble our two scripts. The first one creates the disks, then calls the second one on the remote instance via Invoke-Command.
remote_createstripe.ps1:
$sn = 'arriis'
$n = 'iis1'
$uri = Get-AzureWinRMUri -ServiceName $sn -Name $n
$option = New-PSSessionOption -SkipCACheck -SkipCNCheck
$cred = Get-Credential
Get-AzureVM -ServiceName $sn -Name $n | Add-AzureDataDisk -CreateNew -DiskSizeInGB 128 -DiskLabel "DataDisk0" -LUN 1 | Add-AzureDataDisk -CreateNew -DiskSizeInGB 128 -DiskLabel "DataDisk1" -LUN 2 | Update-AzureVM
$session = New-PSSession -ConnectionUri $uri -SessionOption $option -Credential $cred
Invoke-Command -Session $session -FilePath C:\dev\ps\diskstripe\createstripe.ps1
The second script just creates a text file containing the DISKPART commands and runs it.
createstripe.ps1:
New-Item -Name createstripe.txt -ItemType file -Force
Add-Content -Path createstripe.txt "select disk 2"
Add-Content -Path createstripe.txt "clean"
Add-Content -Path createstripe.txt "convert dynamic"
Add-Content -Path createstripe.txt "select disk 3"
Add-Content -Path createstripe.txt "clean"
Add-Content -Path createstripe.txt "convert dynamic"
Add-Content -Path createstripe.txt "create volume stripe disk=2,3"
Add-Content -Path createstripe.txt "select volume 2"
Add-Content -Path createstripe.txt "assign letter=E"
Add-Content -Path createstripe.txt "format fs=ntfs quick"
diskpart /s createstripe.txt
Hope this helps!