Detecting Wired, Wireless, and VPN Connections using PowerShell

In a recent customer project we needed to detect whether the clients where connected via Wired, Wireless (WiFi) and/or VPN. This was a decent sized environment, about 50K clients, with hardware models from both HP, Dell, and Lenovo. The existing code I had did not work across all the hardware, so I reached out to the ConfigMgr community, and got some great tips from Adam Gross, Vegard Søbstad Alsli, Mattias Cedervall, and Jordan Benzing. After a good few hours of testing, it all ended up with the script further down this post:

The script detects the following VPN platforms

  • Palo Alto GlobalProtect
  • Cisco
  • Juniper
  • Dell VPN (Sonicwall)
  • F5 Networks VPN 

The script filters out the following virtual platform host switches

  • Hyper-V
  • VMware
  • Virtual Box

Update: I replaced the various where-object lines I had with -Filter after getting a friendly tip from Jeffrey Snover on Twitter, after he read this post. Put it this way, there are people you argue PowerShell syntax with, and there are people you don't argue PowerShell syntax with 🙂

Note: If you want the script to output the result as a task sequence variable in ConfigMgr, in this case setting the results as the TSConnectionType variable, simply change the last line to these lines:

# Write-Output "Connection type is: $ConnectionType"
$TSEnv = New-Object -ComObject Microsoft.SMS.TSEnvironment
$TSEnv.Value("TSConnectionType") = $ConnectionType

I would love to get your feedback on the main script.

#Get Connection Type
$WirelessConnected = $null
$WiredConnected = $null
$VPNConnected = $null

# Detecting PowerShell version, and call the best cmdlets
if ($PSVersionTable.PSVersion.Major -gt 2)
{
    # Using Get-CimInstance for PowerShell version 3.0 and higher
    $WirelessAdapters =  Get-CimInstance -Namespace "root\WMI" -Class MSNdis_PhysicalMediumType -Filter `
        'NdisPhysicalMediumType = 9'
    $WiredAdapters = Get-CimInstance -Namespace "root\WMI" -Class MSNdis_PhysicalMediumType -Filter `
        "NdisPhysicalMediumType = 0 and `
        (NOT InstanceName like '%pangp%') and `
        (NOT InstanceName like '%cisco%') and `
        (NOT InstanceName like '%juniper%') and `
        (NOT InstanceName like '%vpn%') and `
        (NOT InstanceName like 'Hyper-V%') and `
        (NOT InstanceName like 'VMware%') and `
        (NOT InstanceName like 'VirtualBox Host-Only%')"
    $ConnectedAdapters =  Get-CimInstance -Class win32_NetworkAdapter -Filter `
        'NetConnectionStatus = 2'
    $VPNAdapters =  Get-CimInstance -Class Win32_NetworkAdapterConfiguration -Filter `
        "Description like '%pangp%' `
        or Description like '%cisco%'  `
        or Description like '%juniper%' `
        or Description like '%vpn%'"
}
else
{
    # Needed this script to work on PowerShell 2.0 (don't ask)
    $WirelessAdapters = Get-WmiObject -Namespace "root\WMI" -Class MSNdis_PhysicalMediumType -Filter `
        'NdisPhysicalMediumType = 9'
    $WiredAdapters = Get-WmiObject -Namespace "root\WMI" -Class MSNdis_PhysicalMediumType -Filter `
        "NdisPhysicalMediumType = 0 and `
        (NOT InstanceName like '%pangp%') and `
        (NOT InstanceName like '%cisco%') and `
        (NOT InstanceName like '%juniper%') and `
        (NOT InstanceName like '%vpn%') and `
        (NOT InstanceName like 'Hyper-V%') and `
        (NOT InstanceName like 'VMware%') and `
        (NOT InstanceName like 'VirtualBox Host-Only%')"
    $ConnectedAdapters = Get-WmiObject -Class win32_NetworkAdapter -Filter `
        'NetConnectionStatus = 2'
    $VPNAdapters = Get-WmiObject -Class Win32_NetworkAdapterConfiguration -Filter `
        "Description like '%pangp%' `
        or Description like '%cisco%'  `
        or Description like '%juniper%' `
        or Description like '%vpn%'"
}


Foreach($Adapter in $ConnectedAdapters) {
    If($WirelessAdapters.InstanceName -contains $Adapter.Name)
    {
        $WirelessConnected = $true
    }
}

Foreach($Adapter in $ConnectedAdapters) {
    If($WiredAdapters.InstanceName -contains $Adapter.Name)
    {
        $WiredConnected = $true
    }
}

Foreach($Adapter in $ConnectedAdapters) {
    If($VPNAdapters.Index -contains $Adapter.DeviceID)
    {
        $VPNConnected = $true
    }
}

If(($WirelessConnected -ne $true) -and ($WiredConnected -eq $true)){ $ConnectionType="WIRED"}
If(($WirelessConnected -eq $true) -and ($WiredConnected -eq $true)){$ConnectionType="WIRED AND WIRELESS"}
If(($WirelessConnected -eq $true) -and ($WiredConnected -ne $true)){$ConnectionType="WIRELESS"}
If($VPNConnected -eq $true){$ConnectionType="VPN"}

Write-Output "Connection type is: $ConnectionType"

About the author

Johan Arwidmark

5 2 votes
Article Rating
Subscribe
Notify of
guest
38 Comments
Newest
Oldest Most Voted
Inline Feedbacks
View all comments
Bob Smith
Bob Smith
11 months ago

Thanks Johan, this article was very helpful

daniel
daniel
1 year ago

Any ideas why our company's F5 Networks VPN Network is never listed in the "connected adapters" var (which lists the netconnectionstatus results). (Windows 10) Why would a connected VPN not show up as connected in the results of:

$ConnectedAdapters = Get-WmiObject Class win32_NetworkAdapter Filter 'NetConnectionStatus = 2' ?

Claudio Mendes
Claudio Mendes
2 years ago

does it support lte detection?

Claudio Mendes
Claudio Mendes
2 years ago

would be nice to add pulse vpn support and maybe something interesting would be a way to check for the connection speed somehow… and maybe not really network stuff but somehow still related could be a check for pluggedin poweradapter ^^

Trevor Jones
3 years ago

You can add this code to detect any connected native VPN connections in W10:
Try
{
$null = Get-Command Get-VPNConnection -ErrorAction Stop
If((Get-VpnConnection | Where {$_.ConnectionStatus -eq "Connected"}))
{
$VPNConnected = $true
}
}
Catch {}

Dietmar Haimann
3 years ago

Hi! Thanks for sharing!
I added the following lines to determine if a mobile connection is used. This works for our HP and Dell notebooks.

$MobileConnected = $Null
$MobileAdapters = Get-CimInstance -Namespace "root\WMI" -Class MSNdis_PhysicalMediumType -Filter `
'NdisPhysicalMediumType = 8'
Foreach($Adapter in $ConnectedAdapters) {
If($MobileAdapters.InstanceName -contains $Adapter.Name) {
$MobileConnected = $true
}
}
If ($MobileConnected -eq $true) {$ConnectionType="MOBILE"}

DHaimann

Dietmar Haimann
3 years ago

In addition I added the following lines $DAConnected = $null $AOConnected = $null # Determine DirectAccess connection $DAConnected = Get-DAConnectionStatus -ErrorAction SilentlyContinue If ($($DAConnected.Status) -eq 'ConnectedRemotely') { $DAConnected = $true $VPNConnected = $true } # Determine AlwaysOn VPN connection # Get-VPNConnection does not work because AOVPN is user initiated # But an additional NetConnectionProfile is active if an AOVPN connection is established $ConnectionProfiles = Get-NetConnectionProfile Foreach($ConnectionProfile in $ConnectionProfiles) { If ($ConnectionProfile.InterfaceAlias -like "*AlwaysOn*") { $IPInterface = Get-NetIPInterface -InterfaceAlias $ConnectionProfile.InterfaceAlias If ($IPInterface.ConnectionState -eq 'Connected') { $AOConnected = $true $VPNConnected = $true } } } # Determine VPN connections If ($VPNConnected -eq… Read more »

Greg
Greg
3 years ago

Just a note for the code. When I cut and pasted it into an editor and tried to run the code, it failed. The cause was an additional space after the backtick on lines 10 and 12

Darrick West
Darrick West
3 years ago

This needs splatting!

Christopher Moriarty
3 years ago

I use something similar, based on SCCM Inventory data from all of our network adapters:

$VPNAdapters = Get-WmiObject -Class Win32_NetworkAdapterConfiguration -Filter "Description like '%vpn%'

Which catches things like "F5 Networks VPN Adapter", et al.

ALIENQuake
ALIENQuake
3 years ago

Please consider excluding VMware/VirtualBox adapters.

ALIENQuake
ALIENQuake
3 years ago

Thanks!

Kevin Severud
Kevin Severud
3 years ago

Converted Get-WmiObject to Get-CimInstance and ran this in PowerShell 7 preview 3 on Win10 1903. It worked. ; – )

Todd
Todd
3 years ago

Hey Johan! How are you consuming the output? This seems like a lot of code for what you might need. In another scenario, we have clients connecting to Thunderbolt Docks which do not show up as 0, but 14. (Similar to what Anthony was saying, but in this instance we would want to include these) I'm not sure why in your script if someone is connected through VPN, that you wouldn't want to also know whether or not they were connected to LAN or WLAN in addition to that. At it's simplest form, you can just use get-netadapter (depending on… Read more »

Daniel Davila
Daniel Davila
3 years ago

Johan, I see $NetworkConfiguration being defined but it's not used elsewhere in the code. Was this part of some earlier PoC? BTW I like this approach. I previously wrote a pre-flight check for a project doing ZTI in-place migrations and checked the registry to retrieve info on each NIC with a media subtype of 0 or blank, then looked up Win32_NetworkAdapter for NetConnectStatus of 2 and not have VPN or Virtual in the ProductName. This looks much cleaner by referencing that root\WMI Namespace. I would still filter out "Virtual" for instances where VMWare or HyperV is installed, but the physical… Read more »

Eric
Eric
3 years ago

You may also want to consider adding a check for remote connection using DirectAccess using Get-DAConnectionStatus. Cheers!

Jamie Miskelly
Jamie Miskelly
3 years ago

Tested on all scenarios. Very useful Johan, thank you.

Marino Tarulli
Marino Tarulli
3 years ago

The string is missing the terminator: ".
+ CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : TerminatorExpectedAtEndOfString

Marino Tarulli
Marino Tarulli
3 years ago

Hi Johan
Thanks for reaching out to me, i found the issue just missing Quotation at last line in # 38.
Now it's working correctly.

Sathish
Sathish
3 years ago

Hi Johan, I tried to use the above script for detecting VPN connection but didn't work on my case, We are using "Sonicwall VPN client" but the description will be like "Dell VPN Adapter" I broke down the script to detect the VPN: $NetworkConfiguration = Get-WmiObject Win32_NetworkAdapterConfiguration $VPNAdapters = $NetworkConfiguration | Where-Object {(($_.Description -ilike "*pangp*") -or ($_.Description -ilike "*Dell*")-or ($_.Description -ilike "*vpn*"))} Foreach($Adapter in $ConnectedAdapters) { If($VPNAdapters.Index -contains $Adapter.DeviceID) { $VPNConnected = $true } } If($VPNConnected -eq $true){$ConnectionType="VPN"} Write-Output "Connection type is: $ConnectionType" When I ran this script it always shows VPN connected, though am not connected with VPN. Please… Read more »

Julian Delaney
Julian Delaney
3 years ago

Haven't had a chance to try this out, but thanks to you (Johan), Adam, Vegard, and Mattias respectively for sharing!

Anthony Fontanez
Anthony Fontanez
3 years ago

This is great! I was just starting to write my own script to do this very same thing. One thing to add is an additional exclusion to line 8 for "*Hyper-V*" to catch those adapters that appear as 802.3.

Anthony Fontanez
Anthony Fontanez
3 years ago

Meant to say connected interfaces in general. I have HV installed on my laptop and your script currently outputs "Connection type is: WIRED AND WIRELESS" when I am really only on wireless. Modifying line 7 to be

$WiredAdapters = Get-WmiObject -Namespace "root\WMI" -Class MSNdis_PhysicalMediumType -Filter "NdisPhysicalMediumType = 0 and NOT InstanceName like '%pangp%' and NOT InstanceName like '%cisco%' and NOT InstanceName like '%juniper%' and NOT InstanceName like '%hyper-v%'"

fixes that.

Andreas Westling
Andreas Westling
3 years ago

Thanks for Sharing! I am using this script with a slight change, we have a ongoing hardware issue with Dell WD15 USB-C docks, together with your logic and added some new (Using Checkpoint VPN), We can locate those machines that running on VPN but really should not since the WD15 dockingstation is plugged in but the physical ethernet cable is glitching 🙂 The cable is "plugged in" but dont have contact… We convinced Dell that we got a really bad batch and will start an exchange of 600 WD15 docks…. Something went wrong in that batch of WD15. We got… Read more »


>