Build cross-subscription Windows lab by using Azure Point to Site VPN

We have several Azure subscriptions each of them has fixed budget, and we would like to build an united development lab base on those subscriptions. Unfortunately the Virtual Machine or Virtual Network in different subscription can’t communicate with each other under Azure policy.

To resolve the barrier, I explored and developed the following methodology which leverage Azure Point to Site VPN to connect Virtual Machines under multiple Azure subscriptions into a single Virtual Network. The diagram below show the idea by an Exchange lab.

P2S across subscription

The first step is setup Virtual Network and Point to Site VPN, you may follow the instruction from Azure:

Next you can setup DNS server and Domain Controller in virtual network, those servers need static IP which it is hard to guarantee if you use P2S VPN to join virtual network.

After you create new VMs in other subscription and install VPN to connect to virtual network, you will need a method to connect P2S VPN automatically during start up before user log on. Here you may use the following script run when start up to make that happen.

The major idea of the script is monitor whether the DNS server can be contacted and then try to resume VPN connection if failed. Also it will refresh route table and register DNS record via VPN connection.

Enjoy it and leverage multiple subscriptions to create an united lab.

The following link help me during the scripting.


Practice of migrate local Exchange testing labs to Azure

We need to migrate 5 local Exchange testing labs (15 VMs, 6 Domain Controllers) to Azure VM, and run Automation testing against those labs after migration complete. This blog elaborate the steps which I tried during the practice.

1. Prepare VM images and upload to Azure.

The local labs host on Hyper-V server. So we just use VHD file as our base images. Azure team provide a guideline to upload VHD and create VM:

In the guideline the VM should be sysprepped before upload, but the VHDs we got are non-sysprepped because they are exported and uploaded to AWS S3 in advance.

For non-sysprepped VHDs, a necessary step for Azure is turning off Windows firewall on PowerShell and remote desktop port. Azure might failed to modify the firewall setting if your VHD is non-sysprepped, then you have no way to connect into your VM.

The VHDs need to be uploaded by Powershell Add-AzureVHD because Azure only support fixed disk type and the command will convert dynamic VHD in upload process.

2. Setup Virtual Network and create VM

The virtual network need to be setup at first, because we can’t modify VNet setting after VM is created.

As the VHD is non-sysprepped and we don’t want Azure to modify our OS settings, we need to create OS disk from VHD, then create VM from OS disk. In this way, we tell Azure just use OS in the disk rather than modify OS as Azure template. It is different with creating VM from image which will copy your VHD to a new one. So it would be better to backup your VHDs before you make major change on OS if you create VM from disk.

After the VM is created, Azure will try to install VM agent in your VM. The operation always fail in my experience, and I believe it is because Azure can’t get administration access in your OS. So you need to install VM agent manually once you could RDP to the VM.

3. Resume Lab

DNS server should be the first VM resumed as other VMs depend on that. DNS server and Domain Controller will need static IP, a PowerShell command Set-AzureStaticVNetIP can be used.

Get-AzureVM ServiceName myvm -Name myvm | Set-AzureStaticVNetIP IPAddress ‘’ | Update-AzureVM

Then you can set DNS server IP address in VNet configure so other VMs could use that DNS server for internal lookup.

Domain controllers should be resumed before Exchange servers. Here we need to discuss more about DNS server setting. I found a robust DNS setting on Azure is setup AD integrated DNS server on domain controller, then setup stub lookup zone on DNS server and point to domain controller. In this way, you don’t need to worry about time synchronization between DNS server and domain controller even you need to frequently shutdown and start up those servers.

For those Exchange servers, an important thing is reconnecting to domain controllers because the DC don’t know who is who after Exchange servers are recreated on Azure. We can reset computer account of the Exchange server on Active Directory Users and Computers, then quit and rejoin domain. Don’t attempt to quit and rejoin domain before reset computer account! That will make your Exchange server a new SID in Domain, it might break a lot of permission or relationship in lab.

It would be worth to rebuild trust if labs have trusts before, because I found some weird issue go away after I rebuild the trusts between domains.

Exchange is designed to start all the time, and have a lot services need to be running to keep Exchange work. But we need to stop and start those labs everyday for Automation Testing. For those services failed to start automatically because dependent service have not been started, we can put them into Automatic Start (Delay) status. Then those services have more chance to start automatically.

4. Azure limitation

Resume labs on Azure have some limitation.

Azure only support Server OS Windows 2008 and Windows 2012 series. So if your lab heavily need client OS or Windows 2003, Azure might not be your choice.

Azure Virtual Network don’t support broadcast. So you had better use FQDN in all your automation testing.

Azure Virtual Network can’t assign IP address per request, can only assign 1 IP address for 1 VM. So those features depends on new IP assignment like Exchange DAG can’t be deployed on Azure.

Use powershell to integrate fitnesse suite testing on Azure VM

I need to trigger Fitnesse test suite and get result in Teamcity build. But the Fitnesse server is different with Teamcity server and I don’t want to install Teamcity Agent on Fitnesse server. And both servers are on Azure VM.

My plan is using Powershell to trigger Fitnesse test suite and retrieve result through HTTP request. The HTTP Uri I used is like: http://%FitnesseServer%/%TestSuite%?suite&format=xml

At the beginning, I use Invoke-WebRequest to send http request. That works well in the suite which execute less than 5 minutes. But once the suite going longer, WebException: “The operation has timed out” is thrown and my Powershell scripting failed to complete.

After further investigation, I found the problem is that Fitnesse will not response anything before the whole suite test is complete. That will hit a lot of timeout mechanism in System.Net.

Then I rewrite my script by using System.Net objects directly, and set all the Timeout properties of HttpWebRequest and related ServicePoint to a proper time. But the ‘timed out’ issue still occur. That move my eye on server side rather than client side.

At last I find that Azure Load Balance has an ‘idle timeout’ setting of 4 minutes. That means if your connection is idle for 4 minutes, Azure may not maintain the connection between service and your application. So the solution is using $request.ServicePoint.SetTcpKeepAlive() to send keep-alive packet during idle time.

Please find the PowerShell script as below, hope that help you to handle similar scenario.


[System.Net.ServicePointManager]::MaxServicePointIdleTime = 30*60*1000
$request = [System.Net.HttpWebRequest][System.Net.WebRequest]::Create($Uri)
$request.Method = “Get”
$request.KeepAlive = $true
$request.Timeout = 30*60*1000
$request.ReadWriteTimeout = 30*60*1000
$request.ProtocolVersion = [System.Net.HttpVersion]::Version11
$request.ServicePoint.ConnectionLeaseTimeout = 30*60*1000
$request.ServicePoint.MaxIdleTime = 30*60*1000
$rp = [System.Net.HttpWebResponse]$request.GetResponse()
$stream = $rp.GetResponseStream()
$reader = New-Object System.IO.StreamReader($stream)
$ret = $reader.ReadToEnd()
if ($null -ne $stream)
if ($null -ne $reader)
if ($null -ne $rp)

The link which help me: