AOVPN Deployment with SCCM – Lessons Learned

We recently completed an AOVPN deployment with SCCM and hit a few bumps along the way,so thought I’d document to help anyone else.  One point to note is, I had nothing to do with the AOVPN solution configuration, just the deployment with SCCM. This information below is a combination of our testing / troubleshooting / questions and answers from redditors / piloting / MS Cases etc.

Our environment

Azure AOVPN Gateways
Device Tunnel Profile (routes for AD services)
User Tunnel Profile (routes for everything else)
SCCM 1810
Win10 1703 – 1909

Microsoft provides the UserCert.ps1 and Devicecert.ps1. After lots of testing and bug finding and troubleshooting, we may some changes to the install script (not what MS does, but before and after). Please note, scripting is not my forte, so the snippets will be clunky (if it looks dumb but it works, it’s not dumb).

We found that we had to make the following changes to the default install scripts;

Script Actions

  1. Uninstall Existing AOVPN Profiles (ensures no conflicting profiles)

  2. Change Regkey to change service dmwappushservice to automatic / start dmwappushservice

  3. Run the standard MS script to create AOVPN Profile

  4. Update the PBK file and change value of IPInterfaceMetric from 0 to 9

  5. Update the PBK file and change value of Ipv6InterfaceMetric from 0 to 9

  6. Update the PBK file and change the value of NetworkOutageTime from 1800 to 30.

  7. Write an XML version Regkey

  8. Set exit code to 1641 (DT only)

Uninstall Existing AOVPN ProfilesWe use a consistent naming convention for our tunnels, so the first few lines of the install script look for any tunnel names and remove them just to ensure no conflicting profiles and also this function helps us later for xml updates. We found that it wasn’t simple to remove an active tunnel. You ahve to hang it up first…however it autoconnects almost immediately. To get around this, we first set the VPN connection to an incorrect authentication method and then disconnect it to prevent it re-dialling;

Set-VPNConnection -AllUserConnection -Name “TunnelName01” -AuthenticationMethod EAP

##Disconnects the AlwaysOnVPN Device Tunnel

Rasdial.exe “TunnelName01” /disconnect

Remove-VPNConnection -AllUserConnection -Name “TunnelName01” -Force -ErrorAction SilentlyContinue

This method is also used for our uninstall scripts.

Change Regkey to change service dmwappushservice to automatic / start dmwappushserviceWe had an issue on an increasing number of machines, where the profile script ran and did not throw any errors and stated that it was all successful, however there was no trace of the tunnel profiles. After much hairpulling and testing and troubleshooting, we eventually found that the service dmwappushservice must be enabled and running for profile creation to occur. So we added this into our install scripts.

###Set registry key to allow WAP Service to start

Set-ItemProperty -Path HKLM:SYSTEMCurrentControlSetServicesdmwappushservice -Name Start -Type DWORD -Value ‘2’ -Force

Start-Sleep -Seconds 5

##Start Service

Set-Service dmwappushservice -startuptype Automatic

Run the standard MS script to create AOVPN ProfileThis is either the Devicecert.ps1 or UserCert.ps1

Update the PBK file and change value of IPInterfaceMetric from 0 to 9We found that users at home, connected to their router via cable had a different experience to those connected via wifi. This was due to some data attempting to go over the ethernet rather than the tunnel (despite having correct routes) and this was due to the ethernet connection having a higher priority than the tunnel connection. Lowering it’s priority resolved this.

Update the PBK file and change value of Ipv6InterfaceMetric from 0 to 9As above, but for IPv6.

**Update the PBK file and change the value of NetworkOutageTime from 1800 to 30.**If a users home ISP briefly dropped connection, it was taking up to 1800 seconds (30 mins) to reconnect. Changing this value reduced that to 30 seconds max. We left it at 30 seconds to cater for longer ISP drops.

PBK File update script snippet. To Update the PBKs we used the following snippets for DT and UT respectively
#Load System PBK
$Syspbk = Get-Content “C:ProgramDataMicrosoftNetworkConnectionsPbkRasphone.pbk”
#Update System PBK Network Metric
$Syspbk | % { $_.Replace(“IpInterfaceMetric=0”, “IpInterfaceMetric=9”) } | % { $_.Replace(“Ipv6InterfaceMetric=0”, “Ipv6InterfaceMetric=9”) } | % { $_.Replace(“NetworkOutageTime=1800”, “NetworkOutageTime=30”) } | Set-Content “C:ProgramDataMicrosoftNetworkConnectionsPbkRasphone.pbk”


#Enumerate currently logged on user$Username = $((Get-WMIObject -class Win32_ComputerSystem | select username).username).split(“”)[1]#Load User PBK$userpath = “C:Users$UsernameAppDataRoamingMicrosoftNetworkConnectionsPbk_hiddenPbk”$Userpbk = Get-Content “$userpathRasphone.pbk”#Update User PBK

$Userpbk | % { $_.Replace(“IpInterfaceMetric=0”, “IpInterfaceMetric=9”) } | % { $_.Replace(“Ipv6InterfaceMetric=0”, “Ipv6InterfaceMetric=9”) } | % { $_.Replace(“NetworkOutageTime=1800”, “NetworkOutageTime=30”) }| Set-Content “$userpathRasphone.pbk”

Write an XML version RegkeyThis was used to track XML versions, but also assist with the update process by utilising Detection Methods. Detailed further down.

**Set exit code to 1641 (DT only)**This tells SCCM to force a reboot (with reboot times honoring the client settings). We found that the DT didn’t always connect immediately, sometimes it took 1 reboot for the auto-always on connection to kick in. We had tight timelines and needed the DT to be deployed, to allow a usercert to be deployed for the UT. So this may not be needed by all people.

Detection Method

Originally, i tried using a powershell script;

if (Get-Command Get-VpnConnection -ErrorAction SilentlyContinue) # Check if the system supports this cmdlet first


if (Get-VPNConnection -AllUserConnection | where {$_.Name -match “Tunnel01”})

{ Write-Host “Installed” }

else {}


else {}

This worked great for Device Tunnel, but not for user tunnel. We are deploying our UT to User Collections, but running as system. Even though it is set to run as system, the detection method runs as User. This is a known bug in sccm (thanks reddit) . In our environment, users are blocked from running powershell, so this wasn’t a suitable method.

We opted for simple regkey detection. Our AOVPN packages look for the presence of the following regkeys;


1)HKLMSYSTEMCurrentControlSetServicesRasManConfigAutoTriggerProfileEntryName = Tunnel01 (system created regkey)2) HKLMSYSTEMCurrentControlSetServicesRasManConfigUTXML = 1.0 (script created regkey, as noted above)


1)HKLMSYSTEMCurrentControlSetServicesRasManDeviceAutoTriggerProfileEntryName = Tunnel02 (system created regkey)2) HKLMSYSTEMCurrentControlSetServicesRasManDeviceDTXML = 1.0 (script created regkey, as noted above)

Updating the solutionTo update the solution, add routes or modify the xmls. We simply add the new xml to the package, update the install script to the new xml version and update the detection method to the new xml version. This forces all devices / users with an old version of the tunnel profiles to reinstall.

DeploymentWe deployed the DT to all devices (using an exclusion collection for devices below 1803 as DT is not supported on those devices).UT we deployed to user collections, but installs as system.

Troubleshooting: The best way to troubleshoot is to always remove as many moving parts from the equation. Most our testing was done using PSExec (system) and running the script with the same parameters that we would when using SCCM.
Event Log: In the event log, look in the applications log for anything from Rasclient for further information. I created a script in SCCM to grab this information remotely and put it on a server share.
Get-EventLog -LogName Application -Newest 100 -Verbose | ft -Wrap > $Path$Compname.EventLog.Application.csv
Get-EventLog -LogName Application -Source Rasclient -Newest 100 -Verbose | ft -Wrap > $Path$Compname.EventLog.RASClient.log
Trace Logs: Advanced Rasclient logs can also be enabled by running the following command on the machine;
netsh ras set tracing * enabled
netsh ras diagnostics set loglevel all
This then writes log files to;

I really hope this helps somebody else out there and you don’t have to do as much head to wall banging.
Best of Luck

1 comment

two × two =

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

Follow us

Don't be shy, get in touch. We love meeting interesting people and making new friends.