I connected the VPN client on a Windows 11 laptop, the tile went to Connected, an internal file share opened, and a public site still loaded straight from the office Wi-Fi. That mix looks like a broken tunnel. It is the normal output of a profile that sends some traffic through the VPN and leaves the rest on the physical adapter. Force tunneling changes which default route Windows prefers; it does not delete more-specific routes, and it does not promise that traffic stops when the connection drops. What follows is the order I work through when a client claims coverage: client state, saved profile, applied routes, resolver, then real flows.

Start at the client, then stop trusting it

The client is the right place to start only because it tells you which profile is active. Open the connection properties and note the exact profile name, whether it was created for the current user or for everyone on the machine, and which adapter appears in ncpa.cpl after connecting. On my test laptop the adapter carried the profile name, which made the route output easy to read. On other machines it shows up as a WAN Miniport entry and the name tells you nothing.

What the client cannot tell you is coverage. A connected tile describes the state of the tunnel, not an inventory of destinations. Third-party clients also keep their own configuration, so the native Windows profile, and every property you are about to read from it, may have nothing to do with what that client installed. If the VPN arrived through AnyConnect, OpenVPN GUI, WireGuard or a vendor agent, the PowerShell checks below mostly do not apply and you should read that client's own split-tunnel and routing settings instead.

Read the saved profile, not the tile

For a native Windows profile (IKEv2, L2TP, SSTP, or one pushed by MDM) the saved split-tunnel decision is a single property:

Get-VpnConnection -Name 'Office' | Select-Object Name, ServerAddress, SplitTunneling, DnsSuffix

Add -AllUserConnection when the profile was created for everyone on the device. Without it you are reading the current user's list, which may be empty or may hold a different entry with a similar name. A value of False in SplitTunneling means the profile was saved as a full tunnel: Windows installs a default route through the VPN adapter. True means split tunnel, and coverage then depends entirely on the routes and name-resolution rules that profile pushes.

Treat that value as configuration, not observation. It records what the profile asked for at connect time. Windows can end up with applied routes that differ, because of another interface's more specific route, a policy setting, or a leftover entry from a previous connection, so the Boolean never settles the question on its own.

Compare the saved value with the applied route table

After connecting, list the routes on the tunnel adapter instead of scrolling the whole table:

$vpn = Get-NetAdapter | Where-Object InterfaceDescription -match 'VPN|WAN Miniport'
Get-NetRoute -InterfaceIndex $vpn.ifIndex | Sort-Object DestinationPrefix
Find-NetRoute -RemoteIPAddress 10.20.4.15 | Select-Object -First 1

Find-NetRoute is the useful half. It answers the question the client never answers: for this destination, which interface and which source address will Windows actually use? Run it for an internal host, a public host, and anything you believe is a deliberate exception. A full-tunnel profile should show the tunnel interface for the public address. A split-tunnel profile usually shows the physical adapter there while internal prefixes still resolve to the VPN.

Two traps explain most "it routes the wrong way" reports. The most specific prefix always wins, so a /24 on the physical adapter beats a default route on the VPN no matter how low the tunnel's metric is. Metric only breaks ties between routes for the same prefix. And IPv4 and IPv6 are decided separately: a profile that covers 0.0.0.0/0 can leave IPv6 on the local link, which makes a dual-stack site look half-tunneled. Check Get-NetRoute -AddressFamily IPv6 before you conclude the tunnel is fine.

What you seeMost likely causeCheck next
Public traffic leaves the physical adapter while SplitTunneling reads FalseA more specific route on that adapter wins over the tunnel defaultFind-NetRoute for the exact destination, then look for a /24 or host route on the physical interface
Internal name fails, internal IP worksNo NRPT rule for that namespace, or a broader rule matches firstGet-DnsClientNrptPolicy and the namespace order
A dual-stack site opens directly while IPv4 uses the tunnelThe profile covers only the IPv4 default routeThe IPv6 route table on both interfaces
Routes look right but one app still goes directThe app uses its own proxy, or the client keeps a per-app listThe app's proxy settings and the client's application list

Check name resolution separately with the NRPT

Internal names that fail while internal IP addresses work point at resolver policy, not routing. Windows decides DNS per namespace through the Name Resolution Policy Table, which is independent of the route table:

Get-DnsClientNrptPolicy -Effective | Select-Object Namespace, NameServers
Get-DnsClientServerAddress -InterfaceIndex $vpn.ifIndex

When a rule matches *.corp.example, queries for that namespace go to the tunnel's DNS servers even if the data path to those servers stays on the physical adapter in split-tunnel mode. That is the design, and it is why a browser test that opens a public site tells you nothing about internal names. If the adapter lists the expected servers but lookups still go elsewhere, compare the NRPT rule order and check whether a more specific namespace is matched first.

Verify the flows, then decide what you actually asked for

Work through destinations in a fixed order so results are comparable across machines: a public address, an internal address, an internal name, and one deliberate exception such as a local printer or a video call. Record the interface and source address Find-NetRoute returns for each. After any policy change, reconnect and repeat the same four checks; the post-reconnect route table is the only evidence that the new profile took effect.

Then separate routing from enforcement. Force tunneling prefers the tunnel for covered traffic while it is up. It is not a kill switch. If the requirement is that nothing leaves the machine when the tunnel drops, that has to come from a blocking design: a firewall profile tied to tunnel state, an always-on profile with traffic filters, or the vendor client's own fail-closed option. Force tunneling also has to leave the VPN server's own address reachable outside the tunnel, and blocking it in the name of "forcing everything" is a reliable way to lock yourself out of the connection you are trying to enforce.

Before you change anything, run through this list. Each item that fails narrows where the real problem sits.

  • Profile name and scope confirmed, with -AllUserConnection used for machine-wide profiles.
  • SplitTunneling read and treated as configuration rather than proof of coverage.
  • Tunnel adapter routes listed for IPv4 and IPv6 separately.
  • Find-NetRoute run for one public, one internal and one exception destination.
  • NRPT rules checked before blaming routes for a name failure.
  • Blocking requirement re-read: preferred routing is not the same as enforced blocking.

The full-tunnel and split-tunnel decision itself belongs to whoever owns the profile, and Microsoft's routing notes describe the behavior Windows implements when a profile sets it. Microsoft: force and split tunneling is the reference I keep open while reading the output.

ХӀокхунах тера йаззамаш