Removing Always On VPN Tunnels

Recently, we were in a situation where we needed to remove some left over Always-on VPN user tunnels from a lot of Windows 10 machines. (We had duplicate profiles, and this was a tidy up exercise)

The following scripts address this issue, it gets a list of all the VPN connections and then removes all the connections. The second script would be used if you wanted to remove all the connections then add the correct profile. We use these scripts with SCCM. This is wrapped into a package and the PowerShell is called from a batch file using psexec.exe.

These scripts are modified versions of scripts originally created by Richard Hicks – if you haven’t already come across his site, and you are working on Direct Access or Always-on VPN, I strongly recommend you head over to his site and take a look! www.richardhicks.com

<#
# 
.SYNOPSIS
    Deletes all Always On VPN user tunnel connections.
.DESCRIPTION
    This script will delete all Always On VPN device tunnels on supported Windows 10 devices. 
.LINK
    https://docs.microsoft.com/en-us/windows-server/remote/remote-access/vpn/always-on-vpn/deploy/vpn-deploy-client-vpn-connections#bkmk_fullscript
.NOTES
    Version:            1.01
    Creation Date:      April 04, 2020
    Special Note:       This script adapted from published guidance provided by Microsoft.
    Original Author:    Microsoft Corporation
    Original Script:    https://docs.microsoft.com/en-us/windows-server/remote/remote-access/vpn/always-on-vpn/deploy/vpn-deploy-client-vpn-connections#bkmk_fullscript
    Author:             Richard Hicks
    Organization:       Richard M. Hicks Consulting, Inc.
    Contact:            ri**@ri**********.com
    Web Site:           www.richardhicks.com
#>
# Lets log the output for troubleshooting.. 
New-Item -ItemType Directory -Force -Path "C:\programdata\AlwaysOnVPN"
Start-Transcript -Path "C:\programdata\AlwaysOnVPN\create_tunnel_transcript.txt" 
# Get the ID and security principal of the current user account
# OMA URI information
$NodeCSPURI = './Vendor/MSFT/VPNv2'
$NamespaceName = 'root\cimv2\mdm\dmmap'
$ClassName = 'MDM_VPNv2_01'
try {

    $Username = Get-WmiObject -Class Win32_ComputerSystem | Select-Object username
    $User = New-Object System.Security.Principal.NTAccount($Username.Username)
    $Sid = $User.Translate([System.Security.Principal.SecurityIdentifier])
    $SidValue = $Sid.Value
    Write-Verbose "User SID is $SidValue."
    Write-Output "User SID is $SidValue." | Out-File C:\ProgramData\AlwaysONVPN\UserSID.txt
}
catch [Exception] {

    Write-Output "Unable to get user SID. User may be logged on over Remote Desktop: $_"
    Write-Output "Unable to get user SID. User may be logged on over Remote Desktop: $_ "| Out-File C:\ProgramData\AlwaysONVPN\SIDError.txt
    #exit
}

$Session = New-CimSession
$Options = New-Object Microsoft.Management.Infrastructure.Options.CimOperationOptions
$Options.SetCustomOption('PolicyPlatformContext_PrincipalContext_Type', 'PolicyPlatform_UserContext', $false)
$Options.SetCustomOption('PolicyPlatformContext_PrincipalContext_Id', "$SidValue", $false)

# delete the profiles
   $deleteInstances = $session.EnumerateInstances($namespaceName, $className, $options)
   foreach ($deleteInstance in $deleteInstances)
   {
   	$InstanceId = $deleteInstance.InstanceID
   	
        $session.DeleteInstance($namespaceName, $deleteInstance, $options)
   		$Message = "Removed $ProfileName profile $InstanceId"
   		Write-Host "$Message"
   	
   }


Write-Output 'Script complete.'
stop-transcript

The second script has a couple of lines you will want to change in lines 32 and 36.

This script removes all Always-on VPN user tunnels and replaces them with the one you specify

<#
# 
.SYNOPSIS
    Creates an Always On VPN user tunnel connection.
.PARAMETER xmlFilePath
    Path to the ProfileXML configuration file.
.PARAMETER ProfileName
    Name of the VPN profile to be created.
.EXAMPLE
    New-AovpnConnection.ps1 -xmlFilePath "C:\Users\rdeckard\desktop\ProfileXML.xml" -ProfileName "Always On VPN User Tunnel"
.DESCRIPTION
    This script will create an Always On VPN device tunnel on supported Windows 10 devices, and delete all other profiles. 
.LINK
    https://docs.microsoft.com/en-us/windows-server/remote/remote-access/vpn/always-on-vpn/deploy/vpn-deploy-client-vpn-connections#bkmk_fullscript
.NOTES
    Version:            1.01
    Creation Date:      April 04, 2020
    Special Note:       This script adapted from published guidance provided by Microsoft.
    Original Author:    Microsoft Corporation
    Original Script:    https://docs.microsoft.com/en-us/windows-server/remote/remote-access/vpn/always-on-vpn/deploy/vpn-deploy-client-vpn-connections#bkmk_fullscript
    Author:             Richard Hicks
    Organization:       Richard M. Hicks Consulting, Inc.
    Contact:            ri**@ri**********.com
    Web Site:           www.richardhicks.com
#>
New-Item -ItemType Directory -Force -Path "C:\programdata\AlwaysOnVPN"
Start-Transcript -Path "C:\programdata\AlwaysOnVPN\create_tunnel_transcript.txt" -NoClobber
cls
###########################################################################
# change this line to point to your vpnrofile.xml that you wish to deploy #
###########################################################################
$xmlFilePath = "C:\ProgramData\AlwaysONVPN\VPNprofile.xml"
##########################################################################
#          Name the connection - this is what users will see!            #
##########################################################################
$ProfileName = "AlwaysON VPN Connection"
# Import ProfileXML
$ProfileXML = Get-Content $xmlFilePath

# Escape spaces in profile name
$ProfileNameEscaped = $ProfileName -replace ' ', '%20'
$ProfileXML = $ProfileXML -replace '<', '&lt;'
$ProfileXML = $ProfileXML -replace '>', '&gt;'
$ProfileXML = $ProfileXML -replace '"', '&quot;'

# OMA URI information
$NodeCSPURI = './Vendor/MSFT/VPNv2'
$NamespaceName = 'root\cimv2\mdm\dmmap'
$ClassName = 'MDM_VPNv2_01'


try {

    $Username = Get-WmiObject -Class Win32_ComputerSystem | Select-Object username
    $User = New-Object System.Security.Principal.NTAccount($Username.Username)
    $Sid = $User.Translate([System.Security.Principal.SecurityIdentifier])
    $SidValue = $Sid.Value
    Write-Verbose "User SID is $SidValue."
    Write-Output "User SID is $SidValue." | Out-File C:\ProgramData\AlwaysONVPN\UserSID.txt


}

catch [Exception] {

    Write-Output "Unable to get user SID. User may be logged on over Remote Desktop: $_"
    Write-Output "Unable to get user SID. User may be logged on over Remote Desktop: $_ "| Out-File C:\ProgramData\AlwaysONVPN\SIDError.txt
    #exit

}

$Session = New-CimSession
$Options = New-Object Microsoft.Management.Infrastructure.Options.CimOperationOptions
$Options.SetCustomOption('PolicyPlatformContext_PrincipalContext_Type', 'PolicyPlatform_UserContext', $false)
$Options.SetCustomOption('PolicyPlatformContext_PrincipalContext_Id', "$SidValue", $false)

# remove all the profiles
 $deleteInstances = $session.EnumerateInstances($namespaceName, $className, $options)
   foreach ($deleteInstance in $deleteInstances)
   {
   	$InstanceId = $deleteInstance.InstanceID
   	
        $session.DeleteInstance($namespaceName, $deleteInstance, $options)
   		$Message = "Removed $ProfileName profile $InstanceId"
   		Write-Host "$Message"
   	
   }

try {

    $NewInstance = New-Object Microsoft.Management.Infrastructure.CimInstance $className, $namespaceName
    $Property = [Microsoft.Management.Infrastructure.CimProperty]::Create('ParentID', "$nodeCSPURI", 'String', 'Key')
    $NewInstance.CimInstanceProperties.Add($Property)
    $Property = [Microsoft.Management.Infrastructure.CimProperty]::Create('InstanceID', "$ProfileNameEscaped", 'String', 'Key')
    $NewInstance.CimInstanceProperties.Add($Property)
    $Property = [Microsoft.Management.Infrastructure.CimProperty]::Create('ProfileXML', "$ProfileXML", 'String', 'Property')
    $NewInstance.CimInstanceProperties.Add($Property)
    $Session.CreateInstance($namespaceName, $NewInstance, $Options)
    Write-Output "Created $ProfileName profile."
    Write-Output "Created $ProfileName profile." | Out-File C:\ProgramData\AlwaysONVPN\CreatedProfile.txt


}

catch [Exception] {

    Write-Output "Unable to create $ProfileName profile: $_"
    Write-Output "Unable to create $ProfileName profile: $_" | Out-File C:\ProgramData\AlwaysONVPN\ProfileCreationError.txt

    exit

}

Write-Output 'Script complete.'
stop-transcript

 

 

Leave a comment

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