Test-VPNConnection Function: Need help testing to see if it works reliably in other environments

Topics: Archive - General
Developer
Sep 28, 2014 at 6:40 AM
Edited Oct 2, 2014 at 11:40 PM
Hey community,

I have developed a function to detect if the system is currently connected via VPN. I want to make sure that it is able to reliably detect VPN connections in other environments as well so I can share it with the community as a general method. Could you please help out by executing this code in your environment and letting me know if it successfully detected the VPN connection? Also, run the code when not connected to VPN so as to make sure that it does not give any false positives.

Thanks!
Function Test-VPNConnection
{
    [CmdletBinding()]
    Param
    (
        [Parameter(Mandatory=$false)]
        [ValidateNotNullorEmpty()]
        [string[]]$NotMatchAdapterDescription = ('^WAN Miniport \(PPPOE\)','^WAN Miniport \(IPv6\)','^WAN Miniport \(Network Monitor\)',
                                                 '^WAN Miniport \(IP\)','^Microsoft 6to4 Adapter','^Microsoft Virtual WiFi Miniport Adapter',
                                                 '^Microsoft WiFi Direct Virtual Adapter','^Microsoft ISATAP Adapter','^Direct Parallel',
                                                 '^Microsoft Kernel Debug Network Adapter','^Microsoft Teredo','^Packet Scheduler Miniport',
                                                 '^VMware Virtual','^vmxnet','VirtualBox','^Bluetooth Device','^RAS Async Adapter','USB'),
        
        [Parameter(Mandatory=$false)]
        [ValidateNotNullorEmpty()]
        [string[]]$LikeAdapterDescription = ('*vpn*','*juniper*','*check point*','*cisco anyconnect*'),
        
        [Parameter(Mandatory=$false)]
        [ValidateNotNullorEmpty()]
        [string[]]$LikeAdapterDNSDomain = ('*.*'),
        
        [Parameter(Mandatory=$false)]
        [ValidateNotNullorEmpty()]
        [string[]]$LikeAdapterDHCPServer,
        
        [Parameter(Mandatory=$false)]
        [ValidateNotNullorEmpty()]
        [string[]]$LikeAdapterDefaultGateway,
        
        [Parameter(Mandatory=$false)]
        [switch]$DisplayNetworkAdapterTable = $false
    )
    
    Begin
    {
        [scriptblock]$AdapterDescriptionFilter = {
            [CmdletBinding()]
            Param
            (
                [Parameter(Mandatory=$true,Position=0,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)]
                $sbInputObject,
                
                [Parameter(Mandatory=$true,Position=1)]
                [string[]]$sbNotMatchAdapterDescription
            )
            
            $SendToPipeline = $true
            ForEach ($sbNotMatchDesc in $sbNotMatchAdapterDescription)
            {
                If ($sbInputObject.Description -imatch $sbNotMatchDesc)
                {
                    $SendToPipeline = $false
                    Break
                }
            }
            
            If ($SendToPipeline)
            {
                Write-Output $sbInputObject
            }
        }
    }
    Process
    {
        Try
        {
            [psobject[]]$AllNetworkAdapter           = Get-WmiObject Win32_NetworkAdapter -ErrorAction 'Stop' |
                                                       Select-Object -Property DeviceID, PNPDeviceID, Manufacturer
            
            [psobject[]]$AllNetworkAdapterConfigTemp = Get-WmiObject Win32_NetworkAdapterConfiguration -ErrorAction 'Stop' |
                                                       Select-Object -Property @{L='DeviceID'; E={$_.Index}}, DNSDomain, DefaultIPGateway, DHCPServer, IPEnabled, PhysicalAdapter, Manufacturer, Description
            
            ForEach ($AdapterConfig in $AllNetworkAdapterConfigTemp)
            {
                ForEach ($Adapter in $AllNetworkAdapter)
                {
                    If ($AdapterConfig.DeviceID -eq $Adapter.DeviceID)
                    {
                        ## Note: We create our own custom PhysicalAdapter property b/c the one in the
                        ##       Win32_NetworkAdapter class is not accurate.
                        $AdapterConfig.PhysicalAdapter        = [boolean]($Adapter.PNPDeviceID -imatch '^PCI\\')
                        $AdapterConfig.Manufacturer           = $Adapter.Manufacturer
                        [psobject[]]$AllNetworkAdapterConfig += $AdapterConfig
                    }
                }
            }
            
            ## This table contains the major markers that might help user create the criteria for detecting VPN connections.
            [string]$AllNetworkAdapterConfigTable   = $AllNetworkAdapterConfig |
                                                      Format-Table DNSDomain, DefaultIPGateway, DHCPServer, IPEnabled, PhysicalAdapter, Manufacturer, Description -AutoSize -Wrap | Out-String
            
            ## Sanitize list of Network Adapters by removing:
            ##  a) physical adapters
            ##  b) adapters which we know are not VPN connections
            [psobject[]]$NetworkAdapterConfig       = $AllNetworkAdapterConfig |
                                                      Where-Object   { -not ($_.PhysicalAdapter) } |
                                                      ForEach-Object {
                                                                        &$AdapterDescriptionFilter -sbInputObject $_ -sbNotMatchAdapterDescription $NotMatchAdapterDescription
                                                                     }
            [string]$NetworkAdapterConfigTable      = $NetworkAdapterConfig |
                                                      Format-Table DNSDomain, DefaultIPGateway, DHCPServer, IPEnabled, PhysicalAdapter, Manufacturer, Description -AutoSize -Wrap | Out-String
            
            ## Sanitize list of Network Adapters by removing:
            ##  a) adapters which are not connected (IP Enabled)
            $NetworkAdapterConfig = $NetworkAdapterConfig | Where-Object { $_.IpEnabled }
            [string]$IpEnabledNetworkAdapterConfigTable = $NetworkAdapterConfig |
                                                          Format-Table DNSDomain, DefaultIPGateway, DHCPServer, IPEnabled, PhysicalAdapter, Manufacturer, Description -AutoSize -Wrap | Out-String
            
            ## Discover VPN Network Adapter by using multiple search criteria.
            ## Search stops at the first match using below precedence order.
            [string]$VPNMatchUsing = ''
            
            #  Precedence Order 1: Detect VPN connection based on key words in network adapter description field.
            If ($LikeAdapterDescription)
            {
                ForEach ($LikeDescription in $LikeAdapterDescription)
                {
                    If ([boolean]($NetworkAdapterConfig | Where-Object {($_ | Select-Object -ExpandProperty Description) -ilike $LikeDescription}))
                    {
                        $VPNMatchUsing = '-LikeAdapterDescription'
                        Return $true
                    }
                }
            }
            
            #  Precedence Order 2: Detect VPN based on DNS domain (e.g.: contoso.com).
            If ($LikeAdapterDNSDomain)
            {
                ForEach ($LikeDNSDomain in $LikeAdapterDNSDomain)
                {
                    If ([boolean]($NetworkAdapterConfig | Where-Object {($_ | Select-Object -ExpandProperty DNSDomain) -ilike $LikeDNSDomain}))
                    {
                        $VPNMatchUsing = '-LikeAdapterDNSDomain'
                        Return $true
                    }
                }
            }
            
            #  Precedence Order 3: Detect VPN connection based on the DHCP Server of the network adapter
            If ($LikeAdapterDHCPServer)
            {
                ForEach ($LikeDHCPServer in $LikeAdapterDHCPServer)
                {
                    If ([boolean]($NetworkAdapterConfig | Where-Object {($_ | Select-Object -ExpandProperty DHCPServer) -ilike $LikeDHCPServer}))
                    {
                        $VPNMatchUsing = '-LikeAdapterDHCPServer'
                        Return $true
                    }
                }
            }
            
            #  Precedence Order 4: Detect VPN connection based on the default gateway for the network adapter.
            If ($LikeAdapterDefaultGateway)
            {
                ForEach ($LikeDefaultGateway in $LikeAdapterDefaultGateway)
                {
                    If ([boolean]($NetworkAdapterConfig | Where-Object {($_ | Select-Object -ExpandProperty DefaultIPGateway) -ilike $LikeDefaultGateway}))
                    {
                        $VPNMatchUsing = '-LikeAdapterDefaultGateway'
                        Return $true
                    }
                }
            }
            Return $false
        }
        Catch
        {
            Return $false
        }
    }
    End
    {
        ## Display Network Adapter Tables
        If ($DisplayNetworkAdapterTable)
        {
            Write-Host "All network adapters: `n$AllNetworkAdapterConfigTable"                                         -ForegroundColor 'Magenta'
            Write-Host "Filtered to possible VPN network adapters: `n$NetworkAdapterConfigTable"                       -ForegroundColor 'Yellow'
            Write-Host "Filtered to possible VPN network adapters (IP Enabled): `n$IpEnabledNetworkAdapterConfigTable" -ForegroundColor 'Cyan'
            If (-not ([string]::IsNullOrEmpty($VPNMatchUsing)))
            {
                Write-Host "VPN Network Adapter matched on search criteria in parameter [$VPNMatchUsing]" -ForegroundColor 'White'
            }
        }
    }
}

## Example of using function
If (Test-VPNConnection -DisplayNetworkAdapterTable)
{
    Write-Host 'VPN Connection Detected'     -ForegroundColor 'Green'
}
Else
{
    Write-Host 'VPN Connection Not Detected' -ForegroundColor 'Red'
}
Developer
Oct 1, 2014 at 4:53 PM
Edited Oct 2, 2014 at 11:37 PM
<#
.SYNOPSIS
    Check to see if there is an active VPN connection.
    
.DESCRIPTION
    Check to see if there is an active VPN connection by using the Win32_NetworkAdapter and the
     Win32_NetworkAdapterConfiguration WMI classes.
    
.PARAMETER NotMatchAdapterDescription
    Excludes on the network adapter description field using regex matching. Precedence order: 0.
    Following WAN Miniport adapters are used for Microsoft Remote Access based VPN
     so are not excluded by default: L2TP, SSTP, IKEv2, PPTP
    
.PARAMETER LikeAdapterDescription
    Matches on the network adapter description field using wild card matching. Precedence order: 1.
    
.PARAMETER LikeAdapterDNSDomain
    Matches on the network adapter DNS Domain field using wild card matching. Precedence order: 2.
    
.PARAMETER LikeAdapterDHCPServer
    Matches on the network adapter DHCP Server field using wild card matching. Precedence order: 3.
    
.PARAMETER LikeAdapterDefaultGateway
    Matches on the network adapter Default Gateway field using wild card matching. Precedence order: 4.
    
.PARAMETER DisplayNetworkAdapterTable
    Logs the full list of network adapters and also the filterd list of possible VPN connection
     network adapters.
    
.EXAMPLE
    Test-VPNConnection
    
.NOTES
    $AllNetworkAdapterConfigTable contains all criteria for detecting VPN connections.
    Try to choose criteria that:
      1) Uniquely identifies the network(s) of interest.
      2) Try not to rely on networking data that may change in future. For example, default gateways
         and DNS and DHCP addresses may change over time or there may be too many to match on.
         Try to use wildcard or regular expression matches if there is an available pattern
         to match multiple values on.
.LINK
#>
Oct 2, 2014 at 10:49 PM
My company uses Microsoft DirectAccess for VPN connectivity. Your script does not detect an active VPN on my system. Output is below. Hope this helps:
All network adapters:

DNSDomain DefaultIPGateway DHCPServer  IPEnabled PhysicalAdapter Manufacturer      Description
--------- ---------------- ----------  --------- --------------- ------------      -----------
                                           False            True Intel Corporation Intel(R) 82579LM Gigabit Network
                                                                                   Connection
                                           False           False Microsoft         Microsoft Kernel Debug Network
                                                                                   Adapter
          {192.168.1.1}    192.168.1.1      True            True Broadcom          Dell Wireless 1504 802.11b/g/n
                                                                                   (2.4GHz)
                                           False           False Microsoft         Microsoft Wi-Fi Direct Virtual
                                                                                   Adapter
                                           False           False                   Microsoft ISATAP Adapter
                                           False           False Microsoft         Bluetooth Device (Personal Area
                                                                                   Network)
                                            True           False VMware, Inc.      VMware Virtual Ethernet Adapter for
                                                                                   VMnet1
                                           False           False                   Microsoft Teredo Tunneling Adapter
                                           False           False Microsoft         Microsoft IP-HTTPS Platform Adapter
                                           False           False                   WAN Miniport (SSTP)
                                           False           False                   WAN Miniport (IKEv2)
                                           False           False                   WAN Miniport (PPPOE)
                                           False           False                   WAN Miniport (PPTP)
                                           False           False                   WAN Miniport (L2TP)
                                           False           False                   WAN Miniport (IP)
                                           False           False                   WAN Miniport (IPv6)
                                           False           False                   WAN Miniport (Network Monitor)
                                           False           False                   RAS Async Adapter
                                           False           False                   Microsoft ISATAP Adapter
                                           False           False Microsoft         Microsoft ISATAP Adapter
                                            True           False VMware, Inc.      VMware Virtual Ethernet Adapter for
                                                                                   VMnet8
                                           False           False Microsoft         Microsoft ISATAP Adapter
                                           False           False Microsoft         Microsoft ISATAP Adapter
                                           False           False                   Microsoft ISATAP Adapter
                                           False           False                   Microsoft ISATAP Adapter
                                           False           False                   Microsoft ISATAP Adapter
                                           False           False                   Microsoft ISATAP Adapter
                                           False           False                   Microsoft ISATAP Adapter



Filtered to possible VPN network adapters:

DNSDomain DefaultIPGateway DHCPServer IPEnabled PhysicalAdapter Manufacturer Description
--------- ---------------- ---------- --------- --------------- ------------ -----------
                                          False           False Microsoft    Microsoft Wi-Fi Direct Virtual Adapter
                                          False           False              Microsoft Teredo Tunneling Adapter
                                          False           False Microsoft    Microsoft IP-HTTPS Platform Adapter
                                          False           False              WAN Miniport (SSTP)
                                          False           False              WAN Miniport (IKEv2)
                                          False           False              WAN Miniport (PPTP)
                                          False           False              WAN Miniport (L2TP)



Filtered to possible VPN network adapters (IP Enabled):

VPN Connection Not Detected
Developer
Oct 2, 2014 at 11:44 PM
Thanks for testing Paul. From the posted results, I am seeing three network adapters which are IP Enabled (have network connection). Two are from VMWare and one is a physical device so cannot be a VPN connection. Did you run the script while you were connected to VPN? The script can only detect the adapter used for VPN connection when connected to VPN. I have updated the code above with a few modifications. Please run it again when connected to VPN and let me know the results. Also, if you know the name of the adapter that the VPN connection uses, that would be great because then I don't have to try and guess if the detection is not working.
Oct 3, 2014 at 4:52 AM
Still not showing that it is connected. And yes I am connected. DirectAccess is Microsoft's transparent always on tunnel. http://technet.microsoft.com/en-us/library/dd759144.aspx

So, it is not anything like a traditional VPN and may not be a good test for your script. But, at the same time is a good test. I did not set it up so I don't pretend to understand how it works. I just know that as soon as I am connected to the internet, I am connected to the work network with DA. It is very slick and is starting to get used more.
All network adapters:

DNSDomain DefaultIPGateway DHCPServer  IPEnabled PhysicalAdapter Manufacturer      Description
--------- ---------------- ----------  --------- --------------- ------------      -----------
                                           False            True Intel Corporation Intel(R) 82579LM Gigabit Network
                                                                                   Connection
                                           False           False Microsoft         Microsoft Kernel Debug Network
                                                                                   Adapter
          {192.168.1.1}    192.168.1.1      True            True Broadcom          Dell Wireless 1504 802.11b/g/n
                                                                                   (2.4GHz)
                                           False           False Microsoft         Microsoft Wi-Fi Direct Virtual
                                                                                   Adapter
                                           False           False                   Microsoft ISATAP Adapter
                                           False           False Microsoft         Bluetooth Device (Personal Area
                                                                                   Network)
                                            True           False VMware, Inc.      VMware Virtual Ethernet Adapter for
                                                                                   VMnet1
                                           False           False                   Microsoft Teredo Tunneling Adapter
                                           False           False Microsoft         Microsoft IP-HTTPS Platform Adapter
                                           False           False                   WAN Miniport (SSTP)
                                           False           False                   WAN Miniport (IKEv2)
                                           False           False                   WAN Miniport (PPPOE)
                                           False           False                   WAN Miniport (PPTP)
                                           False           False                   WAN Miniport (L2TP)
                                           False           False                   WAN Miniport (IP)
                                           False           False                   WAN Miniport (IPv6)
                                           False           False                   WAN Miniport (Network Monitor)
                                           False           False                   RAS Async Adapter
                                           False           False                   Microsoft ISATAP Adapter
                                           False           False Microsoft         Microsoft ISATAP Adapter
                                            True           False VMware, Inc.      VMware Virtual Ethernet Adapter for
                                                                                   VMnet8
                                           False           False Microsoft         Microsoft ISATAP Adapter
                                           False           False Microsoft         Microsoft ISATAP Adapter
                                           False           False                   Microsoft ISATAP Adapter
                                           False           False                   Microsoft ISATAP Adapter
                                           False           False                   Microsoft ISATAP Adapter
                                           False           False                   Microsoft ISATAP Adapter
                                           False           False                   Microsoft ISATAP Adapter



Filtered to possible VPN network adapters:

DNSDomain DefaultIPGateway DHCPServer IPEnabled PhysicalAdapter Manufacturer Description
--------- ---------------- ---------- --------- --------------- ------------ -----------
                                          False           False Microsoft    Microsoft Wi-Fi Direct Virtual Adapter
                                          False           False Microsoft    Microsoft IP-HTTPS Platform Adapter
                                          False           False              WAN Miniport (SSTP)
                                          False           False              WAN Miniport (IKEv2)
                                          False           False              WAN Miniport (PPTP)
                                          False           False              WAN Miniport (L2TP)



Filtered to possible VPN network adapters (IP Enabled):

VPN Connection Not Detected
Developer
Oct 3, 2014 at 10:39 AM
Edited Oct 3, 2014 at 10:40 AM
Thanks for testing again. I did some digging into DirectAccess and it is definitely pretty slick. The best description of it I read was that traditional VPN connects the client to the corporate network. DirectAccess extends the corporate network to the client. I don't have DirectAccess, so if you're willing to work with me and do some testing of my code, I'd like to be able to reliably detect when the user has an active DirectAccess connection to the corporate network.

Based on the research I've done, I'm hoping the below code works to do the detection. If it does not, then the console output should help me modify the code appropriately. Please test and let me know how it goes.
Function Test-DirectAccessCorporateConnectivity
{
    ## Detect if system connected to Microsoft DirectAccess VPN
    [string]$DirectAccessConnectivityReg    = 'HKLM:SOFTWARE\Policies\Microsoft\Windows\NetworkConnectivityStatusIndicator\CorporateConnectivity'
    If (Test-Path -Path $DirectAccessConnectivityReg -ErrorAction 'Stop')
    {
        ## Read connectivity information from registry
        Try
        {
            [psobject]$DirectAccessConnectivity = Get-ItemProperty -Path $DirectAccessConnectivityReg -ErrorAction 'Stop'
        }
        Catch
        {
            Write-Host "Failed to read DirectAccess connectivity information from registry. `n$($_.Exception.Message)"
            Return $false
        }
        
        ## DNS Probing: Resolve Corporate DNS Probe Host Name
        Try
        {
            [string]$DNSProbeHost               = $DirectAccessConnectivity | Select-Object -ExpandProperty 'DnsProbeHost'
            [string]$DNSProbeContent            = $DirectAccessConnectivity | Select-Object -ExpandProperty 'DnsProbeContent'
            Write-Host "DNS Probe Host: $DNSProbeHost"
            Write-Host "DNS Probe Content: $DNSProbeContent"
            
            [string]$DNSProbeHostResolve        = ([System.Net.Dns]::GetHostEntry("$DNSProbeHost"))
            Write-Host "DNS Probe Host Resolution: $DNSProbeHostResolve"
            
            If ($DNSProbeHostResolve -ieq $DNSProbeContent)
            {
                Write-Host "DirectAccess corporate connectivity detected using DNS Probing"
                Return $true
            }
        }
        Catch
        {
            Write-Host "Failed DNS Probing. `n$($_.Exception.Message)"
        }
        
        ## Web Probing: Retrieve Admin Configured Internal Website
        #  The reason for the Web probe is that DirectAccess clients may be located behind a Web proxy server
        #  that performs DNS queries on behalf of the DNS client. Since the DNS client service doesn’t
        #  perform DNS queries for the destination host name for Web proxy clients, this alternate method is required.
        
        Try
        {
            [string]$WebProbeUrl = $DirectAccessConnectivity | Select-Object -ExpandProperty 'WebProbeUrl'
            Write-Host "DNS Web Probe URL: $WebProbeUrl"
            
            If (-not ([string]::IsNullOrEmpty($WebProbeUrl)))
            {
                [System.Net.HttpWebRequest]$request = [System.Net.WebRequest]::Create("$WebProbeUrl")
                $request.Method                     = 'GET'
                $request.Timeout                    = 60000 # = 1 minute
                [System.Net.HttpWebResponse]$result = $request.GetResponse()
                [System.IO.Stream]$stream           = $result.GetResponseStream()
                [System.IO.StreamReader]$reader     = New-Object -TypeName System.IO.StreamReader -ArgumentList $stream
                [string]$output                     = $reader.ReadToEnd()
                
                If (-not ([string]::IsNullOrEmpty($output)))
                {
                    Write-Host "DirectAccess corporate connectivity detected using Web Probing"
                    Return $true
                }
            }
        }
        Catch
        {
            Write-Host "Failed Web Probing. `n$($_.Exception.Message)"
        }
        Finally
        {
            If ($stream)
            {
                $stream.Flush()
                $stream.Close()
            }
        }
    }
    Return $false
}

## Example of using function
If (Test-DirectAccessCorporateConnectivity)
{
    Write-Host 'DirectAccess VPN Connection Detected'     -ForegroundColor 'Green'
}
Else
{
    Write-Host 'DirectAccess VPN Connection Not Detected' -ForegroundColor 'Red'
}
Oct 3, 2014 at 1:50 PM
Edited Oct 3, 2014 at 1:53 PM
See the output below. Seems to work. I replaced our domain with "companydomain".
DNS Probe Host: directaccess-corpConnectivityHost.companydomain.local
DNS Probe Content: fd6b:1593:cf5b:7777::7f00:1
Failed DNS Probing.
Exception calling "GetHostEntry" with "1" argument(s): "No such host is known"
DNS Web Probe URL: http://directaccess-WebProbeHost.companydomain.local
DirectAccess corporate connectivity detected using Web Probing
DirectAccess VPN Connection Detected
If I disable my internet connection, I get the following. I will try it when I get in the office today.
DNS Probe Host: directaccess-corpConnectivityHost.companydomain.local
DNS Probe Content: fd6b:1593:cf5b:7777::7f00:1
Failed DNS Probing.
Exception calling "GetHostEntry" with "1" argument(s): "No such host is known"
DNS Web Probe URL: http://directaccess-WebProbeHost.companydomain.local
Failed Web Probing.
Exception calling "GetResponse" with "0" argument(s): "The remote name could not be resolved: 'directaccess-webprobehost
.companydomain.local'"
DirectAccess VPN Connection Not Detected
Oct 3, 2014 at 2:48 PM
In the office, I get the same response that the connection was detected.
DNS Probe Host: directaccess-corpConnectivityHost.companydomain.local
DNS Probe Content: fd6b:1593:cf5b:7777::7f00:1
Failed DNS Probing.
Exception calling "GetHostEntry" with "1" argument(s): "No such host is known"
DNS Web Probe URL: http://directaccess-WebProbeHost.companydomain.local
DirectAccess corporate connectivity detected using Web Probing
DirectAccess VPN Connection Detected
Developer
Oct 9, 2014 at 10:58 PM
Edited Oct 9, 2014 at 10:59 PM
Thanks for your help with this Paul. I haven't forgotten about this. The function can currently tell if the corporate resources are available or not. It cannot tell if you're at home and connected via VPN or if you're in the office connected directly to the intranet. The second is what I optimally want to be able to determine. However, DirectAccess makes this difficult by default because the default option is to not show the network adapter being used for VPN connection as connected. Because of this, I need to do some more research into how I can reliable detect the DirectAccess VPN connection. Perhaps I can use routing table information for network adapters. Other promising avenues to explore would be to use the INetworkConnection interface introduced in Vista (http://msdn.microsoft.com/en-us/library/aa370751(VS.85).aspx) and/or the GetBestInterfaceEx API. These last two can also give us reliable information on whether or not we are connected to the intranet via wired connection. This would also help us improve the Test-NetworkConnection function in the toolkit because the current WMI method will not necessarily work in all scenarios. Anyways, I will do some more work on this and get back at a later date.