In the last blogpost we looked at how we could use powershell to build an IaaS deployment for SQL Server 2012. The usage was pretty seamless and it really lends itself well to scripted and unattended deployments of VMs. The process we went through showed itself wanting a little in that we had to build in some unwanted manual tasks to get a connection to the SQL Server. We looked at the provision of firewall rules, moving from Windows Authentication to Mixed Mode authentication and then adding a database user in an admin role.

The unfortunate fact is that this process can never be seamless (unlike PaaS) with the default gallery images since you cannot control the running of a startup script (nor would you want to). So to dive in we’ll look into building a powershell script that can do all of the above which can just be copied via remote desktop and executed.

The first part of the script will update the registry key so that we can test our SQL Server connection locally.


#Check and set the LoginMode reg key to 2 so that we can have mixed authentication
 Set-Location HKLM:\
 $registry_key = "SOFTWARE\Microsoft\Microsoft SQL Server\MSSQL11.MSSQLSERVER\MSSQLServer"
 var $item = (Get-ItemProperty -path $registry_Key -name LoginMode).loginmode
 If($item -eq 1) {
 # This is Windows Authentication we need to update
 Set-ItemProperty -path $registry_key -name "LoginMode" -value 2
 }

When this is done we’ll want to open up the firewall port on the machine. Whether we our goal is to use Windows Authentication or Mixed Mode, or only expose the SQL Server to a Windows network that we create as part of an application – so only available internally we’ll still need to open up that firewall port. We do this through the use of a COM object which will allow us to set various parameters such as a port number, range and protocol.


# Add a new firewall rule - courtesy Tom Hollander
 $fw = New-Object -ComObject hnetcfg.fwpolicy2
 $rule = New-Object -ComObject HNetCfg.FWRule
 $rule.Name = "SQL Server Inbound Rule"
 $rule.Protocol = 6 #NET_FW_IP_PROTOCOL_TCP
 $rule.LocalPorts = 1433
 $rule.Enabled = $true
 $rule.Grouping = "@firewallapi.dll,-23255"
 $rule.Profiles = 7 # all
 $rule.Action = 1 # NET_FW_ACTION_ALLOW
 $rule.EdgeTraversal = $false
 $fw.Rules.Add($rule)

Lastly, we will need to add a user that we can test our SQL Server with. This is done through SQL statements and stored procedures. You can see the use of sqlcmd here. This is by far the easiest way although we could have used SMO to do the same thing.


# add the new database user
 sqlcmd -d 'master' -Q "CREATE LOGIN richard1 WITH PASSWORD='icanconnect900'"
 sqlcmd -d 'master' -Q "EXEC sys.sp_addsrvrolemember @loginame = N'richard1', @rolename = N'sysadmin'"

Take all of this and wrap it into a powershell file “.ps1”.

The point of this second post was to show that you could do exactly what we did in the first post programmatically as well. This is what we’ve done through a branch of our Fluent Management library which will now support IaaS. One of the reasons we’ve been very keen to integrate IaaS programmatically is because we feel that the hybrid scenarios of PaaS and IaaS are a great mix so to be able to inevitably this mixture transactional in the same way is a good goal for us.


var manager = new SubscriptionManager(TestConstants.InsidersSubscriptionId);
 manager.GetVirtualMachinesManager()
 .AddCertificateFromStore(TestConstants.ManagementThumbprintIaaS)
 .CreateVirtualMachineDeployment()
 .AddToExistingCloudServiceWithName(TestConstants.CloudServiceNameIaaS)
 .WithDeploymentType(VirtualMachineTemplates.SqlServer2012)
 .WithStorageAccountForVhds(TestConstants.StorageServiceNameIaaS)
 .WithVmOfSize(VmSize.Small)
 .Deploy();

So in one line of code we now have the equivalent of the powershell script in the first part. Note that this is a blocking call. When this returns initially a 202 Accepted response is retuned and then we continue to poll in the background using the x-ms-request-id header as we previously did with PaaS deployments. On success Fluent Management will return unblock.

From the code there are key messages to take away.

  1. we continue to use our management certificate with the subscription activity
  2. we need to provide a storage account for the VHD datadisks
  3. we can control the size of VM which is new thing for us to be able to do in code (normally the VmSize is set in .csdef but in this case we don’t have one or a package)
  4. we have to have a cloud service already existing with which to add the deployment to

In many of the previous posts on this blog we’ve looked at the Service Management API in the context of our wrapper Fluent Management. The new rich set of APIs that have been released for Virtual Machines make for a good set of possibilities to do everything that is easy within the CLI and Powershell right now enabled within an application.

Happy 4th July to all of our US friends (for yesterday!)