How do you update Always on VPN Device tunnel config?

Short version:

According to docs, this config is stored in WMI as XML

How to update it when you need to add some changes - new routes or additional aovpn server or something else stored in that $ProfileXML?

Longer version:

On first thought easy solution to update XML would be to just remove old CIM instance and then create new but there’s downside - if there’s any reason new one won’t be created (some mistake in config or any other reason) - the connection to this remote device might be lost and we’ll need to intervene with manual connection to affected workstation or laptop and do the manual troubleshooting, running scripts etc.

So that’s why I’m looking for a way to update config instead.

My current logic is that every time laptop wakes up from sleep (gets out of idle or lid is open, etc) - a script gets triggered. This script makes multiple checks:

  • if that’s a first run - create vpn profile, create scheduled task, connect

  • if vpn profile exists or not

  • if script is of last version or not

  • if connection to aovpn server and couple intranet resources is working and couple other checks and selfhealth fixes

And among them - it checks if xml config in this script (stored as $hereString object) is equal to what’s in WMI. And I’d like this script to overwrite whatever in WMI - currently working config - with whatever is stored in script.

This is what I have so far:

$session = New-CimSession
$old_xml_ciminstance = Get-CimInstance -ClassName "MDM_VPNv2_01" -Namespace "root\cimv2\mdm\dmmap"
$old_xml_ciminstance.CimInstanceProperties.Item("ProfileXML").set_value($NewProfileXML) 
$null = $session.ModifyInstance($old_xml_ciminstance)

It does seem to be “working”, but there seem to be some kind of a bug- route to currently active RRAS server doesn’t get overwritten - so it duplicates in the end.

For example, if your $ProfileXML (old one) had one route - 10.0.0.5/32 to RRAS server and you add a new one so $NewProfileXML has two routes - 10.0.0.5/32 (RRAS) and 10.1.1.5/32 (some other intranet resource, irrelevant what that is) - after running code from above in WMI there would be 3 routes - one 10.1.1.5/32 (new intranet resource) and two 10.0.0.5/32. My guess is that currently active route can’t get overwritten, so one from previous XML and one from new XML gets added together.

Hence I figured maybe my code is not the right way to update XML config, and if there’s anything else I’m not aware of?

Thanks.

Deploy via Scheduled Task via GPO.

- Runs on logon (because user tunnel - and because user will not notice a quick drop of VPN-connection at this point)

  1. -Robocopies all relevant files (update if new) from server to programfiles
  2. Even if there is no network, those files are already in offline files… We prestage it some days before an update
  3. Updates/Adds any missing Certs to CertStore
  4. Stores current version in registry
  5. Stores desired version in registry (GPP Preference)
  6. Update if current < desired version
  7. Only delete old tunnel (machine|user) if the other tunnel already exist
  8. Tries N times to create the tunnel with Y-wait time (sometimes the tunnel refuse to be created, and the only error code I have gotten out of it was alone the lines of 'a more relevant error code does not exist).
  9. Updates rasphone.pbk in System and User to get correct metrics for VPN-tunnels in case NRPT somehow gets activated in a GPO.

Regarding your approach:

  • Updating the running config (when connect), I do not believe that will work
  • Even if it can work, your config might still mess something up. I concluded delete and create is safer (IIRC even Intune does that)
  • Not sure what you mean by route to RRAS-server. But upon connection to a tunnel windows automatically makes an exception route to the RRAS-server, it will stay there until disconnection.
  • Even if a user somehow gets stuck with a corrupt tunnel, it is fully possible to create a working user tunnel with a non-admin user from the GUI. (to allow any central script to run afterwards)

PowerShell script deployed to the computer via sccm

From what I’ve seen in testing, it doesn’t remove and update cleanly. I’ve had to manually remove from registry. PowerOnPlatforms.com makes a program, with added GPO templates to do this, but it does have a price. If you have Intune it should be able to.

Runs on logon (because user tunnel - and because user will not notice a quick drop of VPN-connection at this point)

Its device tunnel-only setup in my case, I do not have currently and do not plan to use user tunnel at all.

Overall - I will, of course, deploy it with scheduled task using GPO. My question was more about what code exactly do you run to update xml (device tunnel part).

Added longer explanation to post.

I do not have sccm unfortunately, but what kind of powershell script? The updating part of the code to be more specific.

New/Remove-AoVPNConnection from here: GitHub - richardhicks/aovpn: PowerShell scripts and sample ProfileXML files for configuring Windows 10 Always On VPN

Had sccm with internet deployed packages. So clients could run sccm apps when not on VPN. Without it. Not sure… Maybe a convoluted scheduled task to download and run a script from a site you host? (Terrible security idea)

Can you share part of script’s code that specifically handles updating XML config?

It was based off the ms docco Tutorial - Deploy Always On VPN profile for Windows clients | Microsoft Learn

That doc covers creating WMI instance (when there’s none).

So you’re saying you delete old instance and create new one with updated XML, is that correct?

Just re-checked, yep our script deletes the instance first then creates.

Pretty sure we just rerun it