Remove Always On VPN With Powershell (Deployment SCCM/Intune)

Hello,

Recently, I had issues with cleanly removing the Always ON VPN client. Using Remove-VpnConnection
always led to problems, and moreover, it didn’t remove the Regedit keys.

With this script, the necessary keys are deleted and Remove-VpnConnection
works perfectly when you stop and restart the RAS service. I found this out by chance.

This allows for the client to be easily removed on Windows 11 without any issues.

The key to success was really stopping the RasMan service and then restarting it, followed by Remove-VpnConnection. It always works that way. Funny fact: The VPN was obviously not connected, yet it’s necessary to do this; otherwise, it’s a lottery—sometimes it works, sometimes it doesn’t.

ConfigJon was a key for detection rule for SCCM,.

# Stop the RasMan service
Stop-Service -Name RasMan -Force

# Short pause to ensure the service has completely stopped
Start-Sleep -Seconds 5

# Start the RasMan service
Start-Service -Name RasMan

# Short pause to ensure the service has completely started
Start-Sleep -Seconds 5

# Try to remove the VPN connection
try {
    Remove-VpnConnection -AllUserConnection -Name "Always On VPN Device Tunnel" -Force -ErrorAction Stop
    Write-Output "VPN connection successfully removed."
}
catch {
    Write-Error "Error removing the VPN connection: $_"
}

# Path for DeviceTunnel
$regPathDeviceTunnel = "HKLM:\SYSTEM\CurrentControlSet\Services\RasMan\DeviceTunnel"

# Check if the path for DeviceTunnel exists
if (Test-Path $regPathDeviceTunnel) {
	# Retrieve and delete all subkeys
	Get-ChildItem -Path $regPathDeviceTunnel | ForEach-Object {
		Remove-Item -Path $_.PSPath -Recurse -Force
	}

	# Retrieve and delete all values in the key
	Get-Item -Path $regPathDeviceTunnel | ForEach-Object {
		$_.GetValueNames() | ForEach-Object {
			Remove-ItemProperty -Path $regPathDeviceTunnel -Name $_
		}
	}

	Write-Output "All subkeys and values under $regPathDeviceTunnel have been deleted."
}
else {
	Write-Output "The path $regPathDeviceTunnel was not found."
}

# Path for ConfigJon
$regPathConfigJon = "HKLM:\SOFTWARE\ConfigJon"

# Check if the path for ConfigJon exists
if (Test-Path $regPathConfigJon) {
	# Delete the entire ConfigJon folder and its content
	Remove-Item -Path $regPathConfigJon -Recurse -Force
	Write-Output "The folder $regPathConfigJon and all its content have been deleted."
}
else {
	Write-Output "The path $regPathConfigJon was not found."
}

# Path for Tracked
$regPathTracked = "HKLM:\SOFTWARE\Microsoft\EnterpriseResourceManager\Tracked"

# Check if the path for Tracked exists
if (Test-Path $regPathTracked) {
	# Retrieve and delete all subkeys
	Get-ChildItem -Path $regPathTracked | ForEach-Object {
		Remove-Item -Path $_.PSPath -Recurse -Force
	}

	# Retrieve and delete all values in the key
	Get-Item -Path $regPathTracked | ForEach-Object {
		$_.GetValueNames() | ForEach-Object {
			Remove-ItemProperty -Path $regPathTracked -Name $_
		}
	}

	Write-Output "All subkeys and values under $regPathTracked have been deleted."
}
else {
	Write-Output "The path $regPathTracked was not found."
}

Start-Process "rasdial.exe" -ArgumentList '"yourprofilename" /disconnect' -Wait
Get-VpnConnection -AllUserConnection | Remove-VpnConnection -Force

This always worked for me (assuming ran by SYSTEM), never needed to restart service - didn’t even know it’s a thing up until now.

I’m not sure what are these reg keys and why it’s important to remove them though.

Very cool! I remove the VPN connection by using WMI. It will remove the connection even while it is connected. No need to stop any services. You’ll find my PowerShell script here.

https://github.com/richardhicks/aovpn/blob/master/Remove-AovpnConnection.ps1

Enjoy!

Yeah I run something similar on loop till the Get-VPNConnection stops returning the tunnel. (If I have to do it manually, otherwise I usually use Richards disconnect script)

That’s a good approach. It seems the way Windows 11 applies the configuration and tries to creates the reg keys, they don’t always get created or have the correct values when the connection is recreated via intune.

I’ve had to use similar to your script as well as OPs with PSCustomObjects to set them properly for when I need to do it the other way.

I did notice this “bug” was fixed with out of the box windows 11 21H1. It still occasionally happens on Windows 11 22H2 out of the box but always almost happens in in-place upgrades.

Just something for those with W11 to keep an eye out for

Thanx, i know that script allready, i use it, but in our envoirment sometimes it works, sometimes not. I dont know, but i belive it is a issue with Windows 11 22h2

Great Work btw!

Thanks! There was a bug in Windows 11 that prevented that script from working for a while. That’s been fixed now. It should work reliably going forward.