Exchange and .Net Framework compatibility on Azure IAAS.

Tzahi Kolber
4 min readJan 19, 2019

In this blog, I will review the Exchange installation process on Azure IaaS, the .NET compatibility issue that it rises and suggest a solution to the problem.

Background

Exchange’s support policy on Azure IAAS.

According to Microsoft’s, Exchange is supported on Azure IAAS with one important caveat:

“Deployment of Exchange 2016 or Exchange 2019 on Infrastructure-as-a-Service (IaaS) providers is supported if all supportability requirements are met. In the case of providers who are provisioning virtual machines, these requirements include ensuring that the hypervisor being used for Exchange virtual machines is fully supported and that the infrastructure to be utilized by Exchange meets the performance requirements that were determined during the sizing process. Deployment on Microsoft Azure virtual machines is supported if all storage volumes used for Exchange databases and database transaction logs (including transport databases) are configured for Azure Premium Storage.

Problem Statement

As you probably know, Exchange must have .Net Framework, which has to be supported by the Cumulative Update (CU) version you are running.
For more information please visit the Exchange supportability matrix:
https://docs.microsoft.com/en-us/exchange/exchange-server-supportability-matrix-exchange-2013-help#microsoft-net-framework

Exchange’s latest cumulative update is CU11 (at the time of publishing this post), which is the only Exchange CU that supports .NET Framework 4.72.

Now think about a customer that would like to install Exchange on Azure IAAS and the version he is working with is Exchange CU10.
According to the Exchange supportability matrix, the only .Net Framework supported by Exchange CU10 is .Net Framework 4.71:

When you create a VM via the Azure portal, you can choose only one image version out of the Windows 2012 R2, or Windows 2016, for the Exchange 2016 installation.
The Windows 2012 R2 and Windows 2016 images available through the portal are updated with the latest updates, manning it contains .NET Framework 4.72 which, and as stated before, is not supported by Exchange 2016 CU10.

Solution

For this situation, you could choose a different Windows 2012 R2 image from the list using PowerShell.
By running the following command, you get the full list of Windows 2012 R2 (or other), which are currently available:

Get-AzureRmVMImage -Location westeurope -PublisherName MicrosoftWindowsServer -Offer WindowsServer -Skus 2012-R2-Datacenter

or

Get-AzVMImage -Location westeurope -PublisherName MicrosoftWindowsServer -Offer WindowsServer -Skus 2012-R2-Datacenter

The command’s output list contains the date when the image was updated. So in the example above, you can see that the first image in the list was updated on March 15th, 2018 and includes .Net Framework 4.71.

By the way, if you would like to use Windows 2016 versions, you can run the command:

Get-AzureRmVMImage -Location westeurope -PublisherName MicrosoftWindowsServer -Offer WindowsServer -Skus 2016-Datacenter

You can see that Windows Server 2016 Datacenter has many versions, some of them even from 2017, which includes .Net Framework 4.62 only.

  • Please note that the list of builds might be changed from time to time.

Now that I have older builds, how can I run it on Azure?

After selecting the Windows build that includes the .NET version you need for testing your Exchange environment, you can continue and build your machine in Azure.

Using commands in the example below, you can create your VM with Windows 2012 R2 Datacenter version “4.127.20180315”

Sample script

# Variables for common values
$resourceGroup = “RSGnew”
$location = “westeurope”
$vmName = “Exch-Test”
# Create user object
#$cred = Get-Credential -Message “Enter a username and password for the virtual machine.”
# Create user object
$user = “wsadmin”
$password = “Password123456”
$secureStringPwd = $password | ConvertTo-SecureString -AsPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential -ArgumentList $user, $secureStringPwd
# Create a resource group
New-AzureRmResourceGroup -Name $resourceGroup -Location $location
# Create a subnet configuration
$subnetConfig = New-AzureRmVirtualNetworkSubnetConfig -Name newSubnet -AddressPrefix 10.20.0.0/24
# Create a virtual network
$vnet = New-AzureRmVirtualNetwork -ResourceGroupName $resourceGroup -Location $location `
-Name newvNET -AddressPrefix 10.20.0.0/16 -Subnet $subnetConfig
# Create a public IP address and specify a DNS name
$pip = New-AzureRmPublicIpAddress -ResourceGroupName $resourceGroup -Location $location `
-Name “newpublicdns$(Get-Random)” -AllocationMethod Static -IdleTimeoutInMinutes 4
# Create an inbound network security group rule for port 3389
$nsgRuleRDP = New-AzureRmNetworkSecurityRuleConfig -Name newNetworkSecurityGroupRuleRDP -Protocol Tcp `
-Direction Inbound -Priority 1000 -SourceAddressPrefix * -SourcePortRange * -DestinationAddressPrefix * `
-DestinationPortRange 3389 -Access Allow
# Create a network security group
$nsg = New-AzureRmNetworkSecurityGroup -ResourceGroupName $resourceGroup -Location $location `
-Name newNetworkSecurityGroup -SecurityRules $nsgRuleRDP
# Create a virtual network card and associate with public IP address and NSG
$nic = New-AzureRmNetworkInterface -Name newNic -ResourceGroupName $resourceGroup -Location $location `
-SubnetId $vnet.Subnets[0].Id -PublicIpAddressId $pip.Id -NetworkSecurityGroupId $nsg.Id
# Create a virtual machine configuration
$vmConfig = New-AzureRmVMConfig -VMName $vmName -VMSize Standard_A2 | `
Set-AzureRmVMOperatingSystem -Windows -ComputerName $vmName -Credential $cred | `
Set-AzureRmVMSourceImage -PublisherName MicrosoftWindowsServer -Offer WindowsServer -Skus 2012-R2-Datacenter -Version “4.127.20180315” | `
Add-AzureRmVMNetworkInterface -Id $nic.Id
# Create a virtual machine
New-AzureRmVM -ResourceGroupName $resourceGroup -Location $location -VM $vmConfig

Conclusion

Creating an older VM images of Windows rather than those which appears on Azure portal is possible for many purposes, in this case running a Windows versions for Exchange which supports the right .Net Framework version.
Using the Get-AzureRmVMImage command, you can list other VM images which are not listed in the Azure Marketplace.

I would like to Thank Martin Schvartzman for the assistance writing this blog :-)

--

--

Tzahi Kolber

During the last 15 years, I was working as a Senior PFE within Exchange area at Microsoft. Now I’m Senior Consult as Azure IAAS, PowerShell & Automations.