About creating VPN Always On user profile

  • Context

I want to deploy the VPN Always On user tunnel using a logonscript or a scheduled interactive task for non-admin users.

  • Problem

The following Microsoft official learning guides:
Tutorial: Deploy Always On VPN – Configure Always On VPN profile for Windows 10+ clients
Configure an Always On VPN user tunnel

… do provide a single method to do that. It uses the CreateInstance on the WMI class named MDM_VPNv2_01 under the root\cimv2\mdm\dmmap namespace.

Unfortunaletly, it throws the following error:

because it does require admin priviledges. It’s a dead end .

The other issue is that it’s broadly accepted to be redirected to be using inTune or Configuration Manager to deploy a VPN profile or other solutions.
Cannot provision Always On VPN profile to non-admin using Powershell #580
Deploying Always On VPN Profile to non-admin accounts #1820
Is it possible to deploy AOVPN user tunnel using GPO

  • Solution

Why not simply use the built-in Windows cmdlets provided by the VpnClient module?

Get-Command -Module VpnClient

Let’s say, you’ve the XML definition of the EAP configuration.
Here’s an example with contoso.com with 2 VPN servers, 2 DNS servers and suffixes and a class C private network routed through the tunnel where you just use the standard cmdlets provided:

$EAP = @'
    <EapHostConfig xmlns="http://www.microsoft.com/provisioning/EapHostConfig">
      <EapMethod>...</EapMethod>
      <Config xmlns="http://www.microsoft.com/provisioning/EapHostConfig">
      </Config>
    </EapHostConfig>
'@

$HT = @{ ErrorAction = 'Stop' }
try {
    $HTVPN = @{
        ServerAddress = 'vpn01.contoso.com'
        SplitTunneling = [switch]::Present
        DnsSuffix = 'contoso.com'
        TunnelType = 'Automatic'
        EncryptionLevel = 'Required'
        AuthenticationMethod = 'Eap'
        RememberCredential = [switch]::Present
        UseWinlogonCredential = $false
        EapConfigXmlStream = ([xml]$EAP)
        ServerList = ((New-VpnServerAddress -ServerAddress 'vpn01.contoso.com' -FriendlyName 'VPN01'),
                      (New-VpnServerAddress -ServerAddress 'vpn02.contoso.com' -FriendlyName 'VPN02'))
    }
    Add-VpnConnection -Name 'Corp VPN' @HTVPN @HT
    Add-VpnConnectionRoute -ConnectionName 'Corp VPN' -DestinationPrefix '192.168.0.0/16' -RouteMetric 1 @HT
    Add-VpnConnectionTriggerDnsConfiguration -ConnectionName 'Corp VPN' -DnsSuffix '.contoso.com' -DnsIPAddress '192.168.0.100','192.168.0.101' -Force  @HT
    Add-VpnConnectionTriggerDnsConfiguration -ConnectionName 'Corp VPN' -DnsSuffix '.sub.contoso.com' -DnsIPAddress '192.168.0.100','192.168.0.101' -Force  @HT
    Set-VpnConnectionTriggerDnsConfiguration -ConnectionName 'Corp VPN' -DnsSuffixSearchList 'contoso.com'  @HT
    Add-VpnConnectionTriggerTrustedNetwork -ConnectionName 'Corp VPN' -DnsSuffix 'contoso.com' -Force  @HT
} catch {
    Write-Warning -Message "Failed to create user tunnel because $($_.Exception.Message)"
}

Easy or not? 😎

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.