
Deploy an Always On VPN to Azure VPN Gateway for Intune managed devices
In this blog post, you’ll learn about deploying an Always On VPN on Intune-managed devices, connecting to an Azure VPN Gateway.
Generally, building an Always On VPN can be complex. In this post, I’d like to show an option to achieve an Always On VPN deployment more easily.
You’ll learn how to build an Always On VPN deployment leveraging the Azure and Endpoint Management platforms, without having to configure any server infrastructure. In a “traditional” Always On VPN deployment, you have to configure server roles such as:
- Active Directory-based public key infrastructure (PKI) and Active Directory Certificate Services (AD CS)
- Network Policy Server (NPS)
- Routing and Remote Access Server (RRAS)
In this approach, you will deploy an Always On VPN consisting of only:
- An Azure VPN Gateway (VpnGw1 SKU or higher, Basic is not supported)
- A Self-signed VPN Root Certificate, configured on the Azure VPN Gateway
- A Self-signed VPN Child Certificate, deployed to client machines with Microsoft Intune
The Always On VPN client configuration is then deployed to the devices with Microsoft Intune.
Note: While a solution is presented using self-signed certificates, the recommendation is to use a Public Key Infrastructure (PKI) whenever possible. If the self-signed certificate is compromised, unauthorized access to the network could be gained. The same certificate is shared by all users. It is not possible to revoke this certificate (for single users). Resetting access requires replacing the root certificate on the Azure VPN Gateway, then the underlying certificate for all users, which can be a tedious process.
Scenario
Consider the following scenario:
- You manage Azure Active Directory Joined devices with Microsoft Endpoint Manager (Intune)
- You configure an Always On VPN User Tunnel, as Device Tunnel is not supported for Azure AD Joined devices. Only domain-joined devices support a Device Tunnel.
Design considerations
Branch office connectivity
If you need connectivity to branch offices, simply creating Site-to-Site VPN connections from the Azure VPN Gateway is insufficient. You will also need to configure BGP to enable routing from the clients to the branch offices.
Make sure your firewall(s) support IKEv2, route-based VPN tunnels, and BGP. For more information, visit Azure VPN Gateway: About P2S routing – Azure VPN Gateway | Microsoft Docs

Bandwidth
Note that the bandwidth consumed by Always On VPN (P2S) connections is shared with Site-to-Site VPN Connections on the same VPN gateway.
Max connections and pricing
Starting with VpnGw1, a maximum of 250 concurrent VPN connections are supported. Pricing for the first 128 concurrent connections are included, additional P2S connections are priced at $0.01/hour per connection. Consider a connection being up 24/7, this would result in additional costs of $0.01 * 24 hours * 30 days = $7.20 per month per connection. Therefore, in my opinion, this solution is intended for SMEs and not for Large Enterprise companies
More information about VPN Gateways: VPN Gateway Pricing | Microsoft Azure
Always On VPN IKEv2 Features and Limitations
Be aware that IKEv2 comes with some operational challenges. For example, IKEv2 can be blocked, thus preventing users to establish a VPN connection on some networks. Richard Hicks has written a clear article about this on his blog: Always On VPN IKEv2 Features and Limitations | Richard M. Hicks Consulting, Inc. (richardhicks.com)
Configuring the Always On VPN
The configuration of the Always On VPN is divided into several configuration topics:
- Generate the Root & Child VPN certificates
- Configure the Azure VPN Gateway P2S VPN with the Root certificate
- Deploy the Child VPN certificate to the client machines
- Deploy the Always On VPN client configuration
Generate and export the Root & Child VPN certificates
There are multiple ways to achieve the generation of the required certificates. Following the instructions on Microsoft Docs to generate and export certificates for Point-to-Site using PowerShell are sufficient to achieve the required Always On VPN configuration.
Create a self-signed root certificate
Open PowerShell and run the following cmdlet:
$cert = New-SelfSignedCertificate -Type Custom -KeySpec Signature `
-Subject "CN=P2SRootCert" -KeyExportPolicy Exportable `
-HashAlgorithm sha256 -KeyLength 2048 `
-CertStoreLocation "Cert:\CurrentUser\My" -KeyUsageProperty Sign -KeyUsage CertSign -NotAfter (Get-Date).AddYears(5)
Generate a client certificate
With the PowerShell console still open, run the following cmdlet:
New-SelfSignedCertificate -Type Custom -DnsName P2SChildCert -KeySpec Signature `
-Subject "CN=P2SChildCert" -KeyExportPolicy Exportable `
-HashAlgorithm sha256 -KeyLength 2048 `
-CertStoreLocation "Cert:\CurrentUser\My" `
-Signer $cert -TextExtension @("2.5.29.37={text}1.3.6.1.5.5.7.3.2") -NotAfter (Get-Date).AddYears(5)
Export the root certificate public key (.cer)
In the Current User’s Personal Certificate Store (accessible via certmgr.msc), export the P2SRootCert without the Private Key as Base-64 encoded X.509 (.CER) to a location of your choosing.

Open the .CER file with Notepad, you’ll see something similar to the example below. You will configure the section highlighted in blue on the Azure VPN Gateway P2S configuration later.

Export the client certificate
To authenticate to the Always On VPN seamlessly, users need the client certificate, containing the Private Key, installed on their device. Export the client certificate to the location of your choosing. Make sure to export the certificate:
- Including the private key
- As Personal Information Exchange -PKCS #12 (.PFX)
- With a password.
You will distribute this certificate to the endpoints with Microsoft Intune later.

Configure the Azure VPN Gateway P2S VPN with the Root certificate
If you haven’t deployed the Azure VPN Gateway yet, check out the tutorial to create and manage a VPN gateway. Assuming an Azure VPN Gateway is available, you’ll need to set up the Point to Site VPN configuration.
On the Azure VPN Gateway navigate to the Point-to-site configuration, you will now configure the address pool, tunnel type, and authentication type.
If you don’t see tunnel type or authentication type on the Point-to-site configuration page, your gateway is using the Basic SKU. The Basic SKU does not support IKEv2 or RADIUS authentication. To enable these settings, you will need to update to atleast a Standard gateway SKU.
- Address pool: Enter an IP range in which the VPN clients will obtain an IP address when setting up a VPN connection.
- Tunnel type: Select IKEv2
- Authentication type: Select Azure certificate
Earlier you’ve exported the Root certificate public key (.cer), when opened with Notepad, upload the blue highlighted text to the Azure Point-to-Site VPN configuration.

Click Save to finish the Point-to-Site configuration.
When the configuration is completed, click Download VPN client. In the .zip file, navigate to the Generic folder and open the VpnSettings.xml file in an editor of choice. Take note of the value in the <VpnServer> element, which is required to build the configuration for the VPN connection later. For example, this looks like: azuregateway-5a5b0069-386a-4254-90f2-c11c14cb4dc7-ddb9fa020695.vpn.azure.com
Deploy the Child VPN certificate to the client machines
To authenticate with the Azure VPN gateway, the Child VPN certificate, including the private key (.PFX), needs to be installed on each client machine.
Unfortunately, the deployment of a .PFX certificate cannot be accomplished with device configuration profiles. Instead, it is necessary to deploy the Child VPN certificate as a Win32 (.intunewin) app in User context. A benefit of doing so is that Win32 apps can be tracked during the Enrollment Status Page, so as soon as users log on to their device for the first time, the Always On VPN is already good-to-go.
Create the following file- and folder structure:
- P2SChildCert (Folder)
- Source (Folder)
- P2SChildCert.pfx
- install.ps1
- uninstall.ps1
- Package (Folder)
- detection.ps1
- Source (Folder)
Put the P2SChildCert.pfx in the Source folder, that you exported earlier.
Add the following PowerShell code to the install.ps1, uninstall.ps1 and detection.ps1 files, make sure to edit the password and possibly the certificate name accordingly.
install.ps1
$PfxPassword = "MyVPNChildCertPassword"
$SecurePassword = $PfxPassword | ConvertTo-SecureString -AsPlainText -Force
$Path = ($MyInvocation.MyCommand.Path -split "install.ps1")[0]
Import-PfxCertificate -FilePath "$Path\P2SChildCert.pfx" -CertStoreLocation Cert:\CurrentUser\My -Password $SecurePassword
uninstall.ps1
Get-ChildItem -Path Cert:\CurrentUser\My | Where-Object { $_.Subject -eq "CN=P2SChildCert" } | Remove-Item
detection.ps1
if ((Get-ChildItem -Path Cert:\CurrentUser\My).Subject -eq "CN=P2SChildCert") {
Write-Output "Found a match!"
} else {
Write-Error "Did not find a matching certificate!" -ErrorAction Stop
}
Now package the content of the Source folder as .intunewin, saved in the Package folder with the Win32 Content Prep Tool.
IntuneWinAppUtil.exe -c “Source” -s “Source\install.ps1” -o “Package”
Now that the app is packaged to an intunewin file, add a new Windows app (Win32) in the Microsoft Endpoint Manager admin center. Configure the app with the following details:
Install command: powershell.exe -executionpolicy bypass -windowstyle hidden -file “install.ps1”
Uninstall command: powershell.exe -executionpolicy bypass -windowstyle hidden -file “uninstall.ps1”
Install behavior: User
Device restart behavior: No specific action
Rules format: Use a custom detection script. (Upload the detection.ps1 script)
Save the application and assign it to your users.
Deploy the Always On VPN client configuration
Now that the VPN Gateway is deployed and the certificates are in place, it’s time to create the Intune configuration that deploys the Always On VPN connection to your client machines.
In the Microsoft Endpoint Manager Admin Center, create a new configuration profile.
- Select Windows 10 and later as platform.
- Select Templates as Profile type
- Create a new configuration profile based on the VPN template.

4. Enter a name for the configuration profile, e.g. Always On VPN, and click Next.

5. Expand the Base VPN section.
- Connection name: Enter a name for the Always On VPN connection. This is how the VPN connection is displayed on the end user’s device.
- Servers:
- Enter the VPN server address you’ve collected earlier in the VpnSettings.xml file.
- Enter a description for the VPN server.
- Set the value for default server to true.
- Connection Type: Select IKEv2.
- Always On: Select Enable.
- Remember credentials at each logon: Select Enable.
- Authentication method: Select EAP.
- EAP xml: Enter the EAP configuration shown below. For example this is a basic EAP xml configuration that is sufficient for the Always On VPN connection to establish.
<EapHostConfig xmlns=”http://www.microsoft.com/provisioning/EapHostConfig”><EapMethod><Type xmlns=”http://www.microsoft.com/provisioning/EapCommon”>13</Type><VendorId xmlns=”http://www.microsoft.com/provisioning/EapCommon”>0</VendorId><VendorType xmlns=”http://www.microsoft.com/provisioning/EapCommon”>0</VendorType><AuthorId xmlns=”http://www.microsoft.com/provisioning/EapCommon”>0</AuthorId></EapMethod><Config xmlns=”http://www.microsoft.com/provisioning/EapHostConfig”><Eap xmlns=”http://www.microsoft.com/provisioning/BaseEapConnectionPropertiesV1″><Type>13</Type><EapType xmlns=”http://www.microsoft.com/provisioning/EapTlsConnectionPropertiesV1″><CredentialsSource><CertificateStore><SimpleCertSelection>true</SimpleCertSelection></CertificateStore></CredentialsSource><ServerValidation><DisableUserPromptForServerValidation>false</DisableUserPromptForServerValidation><ServerNames></ServerNames></ServerValidation><DifferentUsername>false</DifferentUsername><PerformServerValidation xmlns=”http://www.microsoft.com/provisioning/EapTlsConnectionPropertiesV2″>false</PerformServerValidation><AcceptServerName xmlns=”http://www.microsoft.com/provisioning/EapTlsConnectionPropertiesV2″>false</AcceptServerName></EapType></Eap></Config></EapHostConfig>
- Device Tunnel: Make sure that this is set to disable. Only a User tunnel is supported.

6. Expand the DNS Settings section.
- DNS suffixes: Optionally add your domain’s DNS suffixes
7. Expand the Split Tunneling section
To prevent all traffic from going through the VPN, you can enable split tunneling so that only traffic to corporate networks is routed through the VPN connection. Below is an example to enable only traffic to your Azure Virtual Network subnet through the VPN.
- Split tunneling: Enable
- Split tunneling routes for this VPN connection:
- Destination prefix: <Enter your Azure Virtual Network subnet>
- Prefix size: <Enter your Azure Virtual Network subnet prefix size>

8. Expand the Trusted Network Detection.
Client machines will automatically establish the Always On VPN connection on any network. By configuring Trusted network DNS suffixes, client machines can detect when they are on a trusted network and will not automatically establish a VPN connection on these networks.
- Trusted network DNS suffixes: <Optionally add your domain’s DNS suffixes”>
10. Create and assign the Always On VPN configuration to your users.
Result
When your client machines synchronize with Intune, the Always On VPN configuration profile will apply and clients will start to connect with the Azure VPN gateway.

With the Always On VPN connection established, it is now possible to reach corporate resources from any network.

12 thoughts on “Deploy an Always On VPN to Azure VPN Gateway for Intune managed devices”
Another option for certificates is using the CA in Azure AD Conditional Access.
https://docs.microsoft.com/en-us/windows-server/remote/remote-access/vpn/vpn-create-root-cert-for-vpn-auth-azure-ad
A lot easier than the hassle of creating root certs and child certs.
What settings in the article would need to be changed (and what to) and what additional steps would need to be done in order to use the Conditional Access CA method correctly?
Hi Philip, I just posted a new article explaining the Conditional Access option. Feel free to check it out at https://srdn.io/2022/02/how-to-deploy-an-always-on-vpn-to-azure-vpn-gateway-with-conditional-access/
Hi John,
Thanks a lot for this article, it’s very useful, I was curious to see what additional steps would be required if an ADCS was used instead, would there be a need for a certificate connector within Intune, along with cert profiles configured? Wondering how I can use the Azure GW VPN but utilise a PKI environment too and deliver to endpoints via Intune.
Thanks again,
Alex.
Hi Alex,
I just posted a new article explaining the Conditional Access option. Feel free to check it out at https://srdn.io/2022/02/how-to-deploy-an-always-on-vpn-to-azure-vpn-gateway-with-conditional-access/
Hi,
Always On VPN is still not supported in cloud, at least what I can find. Any comments on that?
Hi Henrik,
Some Windows features, such as RRAS are not supported in Azure. I have no references to an Azure VPN Gateway not being supported.
Best regards,
John
Thanks for the info. Are you able to resolve dns host names through vpn this route? For instance, connecting to a sql database from a P2S client?
Yes, I’m doing this myself albeit with VMs. All the guidance I’ve seen talks about DNS forwarders or even more complex solutions. All I did was peer the VPN vnet with my AADDS vnet and add my custom DNS servers into the config for the VPN vnet.
I’m no expert (otherwise I wouldn’t be on this page) but I think you also need to include the required routes under split tunneling too.
Hi John,
Is it possible to deploy client configuration using .xml file instead of Intune? Thank you.
This is gold for a small startup. I couldn’t find anything else that even comes close to giving the right guidance and instructions. Everything else I’ve seen seems to be based on hybrid joining rather than a fully remote workforce using AADDJ.
Followed this and it all works a charm.