Always On VPN vs DirectAccess: Why the Upgrade Matters
Always On VPN (AOVPN) is Microsoft’s modern replacement for DirectAccess, introduced with Windows 10 and Windows Server 2016. While DirectAccess provided transparent remote access using IPv6-over-IPv4 tunneling and IPsec, it was tightly coupled to Active Directory group policy, required IPv6 infrastructure, only supported domain-joined Windows Enterprise clients, and was notoriously complex to troubleshoot. Always On VPN addresses all of these shortcomings.
AOVPN uses standard VPN protocols (IKEv2, SSTP, L2TP, OpenVPN) over IPv4 and IPv6. It supports both domain-joined and Azure AD-joined devices. It supports Windows 10/11 Professional and Enterprise editions. The “always on” behavior is driven by the VPNv2 configuration service provider (CSP), which can be deployed via Microsoft Intune, System Center Configuration Manager (SCCM/MECM), PowerShell, or Group Policy. AOVPN is fully compatible with Conditional Access in Azure AD, enabling MFA and device compliance enforcement at the VPN connection level.
This guide walks through deploying Always On VPN using Windows Server 2022 as the RRAS VPN gateway with NPS for RADIUS authentication.
Infrastructure Requirements and Component Overview
A complete Always On VPN deployment on Windows Server 2022 requires the following components:
RRAS Server — The VPN gateway. This server runs Windows Server 2022 with the Remote Access role. It should have two NICs: one connected to the internet (public-facing) and one connected to the internal network. Place it in a perimeter network (DMZ) or behind a firewall with appropriate NAT rules.
NPS Server (Network Policy Server) — Acts as a RADIUS server for VPN client authentication. Can be co-located with RRAS on small deployments, but should be separate in production for scalability. NPS authenticates users against Active Directory and can enforce connection policies (time-of-day, group membership, device compliance).
PKI (Certificate Authority) — AOVPN requires certificates for multiple purposes: a VPN Server certificate (for the RRAS server), a User Authentication certificate (for EAP-TLS user auth), a Device/Machine certificate (for Device Tunnel), and an NPS certificate (for PEAP or EAP-TLS RADIUS auth). An Active Directory Certificate Services (ADCS) enterprise CA is the standard approach.
DNS — The VPN server must resolve the VPN server’s public FQDN (e.g., vpn.contoso.com) externally. Internal DNS must be accessible to connected VPN clients.
Setting Up RRAS as a VPN Server
Install the Remote Access role with the DirectAccess-VPN and Routing sub-features on the RRAS server:
Install-WindowsFeature -Name DirectAccess-VPN, Routing -IncludeManagementTools
After installation, launch the Routing and Remote Access MMC (rrasmgmt.msc) or use PowerShell to configure RRAS as a VPN server:
# Configure RRAS for VPN-only (no NAT, no DA)
Install-RemoteAccess -VpnType VpnS2S
# or for full VPN server setup:
Set-RemoteAccess -VpnType Vpn
In the RRAS wizard, select “Custom Configuration” and check “VPN Access”. After the service starts, configure the IP address pool for VPN clients. RRAS can assign IP addresses from a static pool or via DHCP from your internal network. Configure a static pool via PowerShell:
Add-VpnServerIPv4AddressRange -StartIPAddress 10.200.0.1 -EndIPAddress 10.200.0.254
Configure RRAS to use NPS for RADIUS authentication (do not authenticate locally):
Set-VpnAuthProtocol -UserAuthProtocolAccepted EAP, MSChapv2 -TunnelAuthProtocolsAdvertised EAP
Set-RemoteAccessRadius -ServerName "NPS01.contoso.com" -SharedSecret "RadiusSecret!" -AccountingOnOffMsg Enabled -Score 10
Installing and Configuring NPS for RADIUS Authentication
On the NPS server, install the Network Policy Server role:
Install-WindowsFeature -Name NPAS -IncludeManagementTools
Register NPS in Active Directory so it can read user dial-in properties:
netsh nps add registeredserver
Or via the NPS console: right-click “NPS (Local)” and select “Register server in Active Directory”. Open the NPS console (nps.msc) and configure the RRAS server as a RADIUS client. Navigate to RADIUS Clients and Servers > RADIUS Clients, add a new entry with the RRAS server’s internal IP and the shared secret configured on the RRAS server.
Create a Network Policy that allows VPN connections for members of a specific AD security group (e.g., VPN-Users):
# Via NPS console:
# Network Policies > New Policy
# Condition: Windows Groups = DOMAINVPN-Users
# Condition: NAS Port Type = Virtual (VPN)
# Grant Access
# Authentication Method: Microsoft EAP (PEAP or EAP-TLS)
# Constraints: Day and Time (optional)
Ensure the NPS server has a computer certificate enrolled from your ADCS CA for PEAP/EAP-TLS authentication. Without this certificate, PEAP authentication will fail.
PKI Certificate Requirements
The certificate infrastructure is the most complex part of AOVPN. The VPN Server certificate must be issued to the server’s public FQDN (vpn.contoso.com), have Server Authentication (1.3.6.1.5.5.7.3.1) in the Enhanced Key Usage, and must be trusted by the VPN clients. If you use an internal CA, push the CA root certificate to clients via Group Policy or Intune.
Create a certificate template for the VPN Server in ADCS:
# On the CA server, duplicate the Web Server template
# Name it "VPN Server"
# Subject Name: Supply in request
# EKU: Server Authentication
# Key Usage: Digital Signature, Key Encipherment
# Request handling: Allow private key to be exported (optional)
# Security: VPN server computer account = Enroll
Request the certificate on the RRAS server via PowerShell or certlm.msc. Ensure the Subject Alternative Name (SAN) includes the public FQDN:
$cert = Get-Certificate -Template "VPNServer" `
-SubjectName "CN=vpn.contoso.com" `
-DnsName "vpn.contoso.com" `
-CertStoreLocation "Cert:LocalMachineMy"
For User Tunnel with certificate authentication (EAP-TLS), users need a User Authentication certificate. Create a template with Client Authentication EKU and deploy it via autoenrollment Group Policy. For Device Tunnel, computers need a Machine Authentication certificate — deploy via Group Policy or Intune autoenrollment.
Device Tunnel vs User Tunnel
Always On VPN supports two tunnel types that serve different purposes and can be deployed simultaneously:
User Tunnel — Connects after a user logs in. Authenticates the user (via EAP-TLS with user certificate, or PEAP with username/password). Provides access to internal resources for the logged-in user. This is the primary tunnel for end-user remote access.
Device Tunnel — Connects before user login (pre-logon). Authenticates using the machine certificate. Provides connectivity for domain authentication (Kerberos/NTLM) before the user logs in, enabling Group Policy updates, logon scripts, and domain controller communication at boot time. Device Tunnel requires Windows 10/11 Enterprise and must use IKEv2 with machine certificate authentication. Only one Device Tunnel profile can exist per device.
Deploy both tunnels together for the optimal remote work experience: Device Tunnel handles pre-logon domain authentication, and User Tunnel handles post-logon user access.
Creating and Deploying the VPN Profile XML
Always On VPN is configured using a VPNv2 CSP XML profile. Below is a functional User Tunnel profile for IKEv2 with EAP-TLS authentication:
true
contoso.com
vpn.contoso.com
SplitTunnel
IKEv2
Eap
25
0
0
0
10.0.0.0
8
172.16.0.0
12
Deploy this profile via PowerShell using the VPNv2 WMI bridge (works for the current user in user context):
$ProfileName = "Contoso Always On VPN"
$ProfileXML = (Get-Content "C:VPNProfileUserTunnel.xml" -Raw)
# Encode for WMI
$ProfileXML_Escaped = $ProfileXML -replace '', '>' -replace '"', '"'
$nodeCSP = "./User/Vendor/MSFT/VPNv2/$ProfileName/ProfileXML"
$WmiObj = Get-CimInstance -Namespace rootcimv2mdmdmmap -ClassName MDM_VPNv2_01 `
-Filter "ParentID='./User/Vendor/MSFT/VPNv2' and InstanceID='$ProfileName'"
if ($WmiObj) {
Set-CimInstance -CimInstance $WmiObj -Property @{ProfileXML=$ProfileXML_Escaped}
} else {
$NewInstance = New-Object Microsoft.Management.Infrastructure.CimInstance "MDM_VPNv2_01", "rootcimv2mdmdmmap"
$NewInstance.CimInstanceProperties.Add([Microsoft.Management.Infrastructure.CimProperty]::Create("ParentID","./User/Vendor/MSFT/VPNv2",[Microsoft.Management.Infrastructure.CimType]::String,1))
$NewInstance.CimInstanceProperties.Add([Microsoft.Management.Infrastructure.CimProperty]::Create("InstanceID",$ProfileName,[Microsoft.Management.Infrastructure.CimType]::String,1))
$NewInstance.CimInstanceProperties.Add([Microsoft.Management.Infrastructure.CimProperty]::Create("ProfileXML",$ProfileXML_Escaped,[Microsoft.Management.Infrastructure.CimType]::String,0))
$Session = New-CimSession
$Session.CreateInstance("rootcimv2mdmdmmap", $NewInstance)
}
For enterprise deployments, use Intune Device Configuration profiles (Windows > VPN profile template) or deploy via MECM/SCCM Configuration Items targeting the VPNv2 CSP. Intune provides the cleanest deployment path for Azure AD-joined devices.
Force Tunnel vs Split Tunnel
In Split Tunnel mode (the default), only traffic destined for specified internal subnets goes through the VPN. Internet traffic goes directly from the client’s local internet connection. This reduces load on the VPN server and provides better performance for cloud services. Configure split tunnel by specifying Route elements in the profile XML (as shown above).
In Force Tunnel mode, all client traffic is routed through the VPN, including internet traffic. This provides maximum security and allows central internet filtering but increases VPN server load and latency. Configure Force Tunnel by setting RoutingPolicyType to ForceTunnel in the profile XML. Force Tunnel requires careful planning — ensure the VPN server has adequate bandwidth and that internet-bound traffic is filtered appropriately (via proxy or firewall at the internal network egress).
Monitoring and Troubleshooting Always On VPN
Monitor active VPN connections on the RRAS server:
Get-RemoteAccessConnectionStatistics
Get-RemoteAccessUserActivity -HostIPAddress 10.200.0.1
On the client, check VPN connection status:
Get-VpnConnection -Name "Contoso Always On VPN" | Select-Object *
Get-VpnConnectionTrigger -ConnectionName "Contoso Always On VPN"
The primary client-side diagnostic is the RasClient event log. Open Event Viewer and navigate to Applications and Services Logs > Microsoft > Windows > RasClient > Operational. Event ID 20227 indicates a successful connection. Event ID 20226 indicates a disconnection. Event IDs in the 20000-20299 range cover all RAS connection lifecycle events.
The rasphone.pbk file stores VPN phonebook entries on clients. For system (Device Tunnel) connections, it is located at C:ProgramDataMicrosoftNetworkConnectionsPbkrasphone.pbk. For user tunnels, it is at %APPDATA%MicrosoftNetworkConnectionsPbkrasphone.pbk. Check this file to verify the profile settings were deployed correctly.
For IKEv2 authentication failures, enable verbose logging on the RRAS server:
netsh ras set tracing * enabled
# Reproduce the issue
# Logs appear in C:Windowstracing
netsh ras set tracing * disabled
Always On VPN with Windows Server 2022 provides a robust, standards-based remote access solution that integrates deeply with Active Directory, Azure AD Conditional Access, and modern device management platforms, making it the recommended remote access architecture for Windows-based enterprise environments.