The laptop connects to the office VPN and everything follows it, including a printer's web page and one intranet that only answers on the local network. A hand-made route fixes that for an hour, then the connection drops, comes back, and the exception is gone. Nothing is wrong with the tunnel: Windows keeps a single routing table, and the VPN adapter rewrites its share of that table on every connect. What survives is whatever lives outside the adapter's own entries.

Which entry the tunnel takes over

Record the table twice, once with the tunnel down and once with it up, and compare the default lines. When the profile claims the default prefix, the adapter's entry is the widest row in the table, so any exception has to be narrower than it. That is arithmetic about prefix length rather than a statement about trust or policy. It also fixes which interface the exception has to name.

Write down the interface index and the local gateway before moving on, because both change when the machine joins another network. The commands below read them from the machine rather than from memory.

route print -4
Find-NetRoute -RemoteIPAddress 198.51.100.30

The second command reports the interface and next hop that one address would use right now, which beats reading forty rows and guessing. Run it before and after connecting and you have the pair worth attaching to a change record. Both outputs supply the numbers used in the rest of this page.

A host route wins on specificity

Longest-prefix match decides the winner, so a /32 through the physical gateway beats the default through the tunnel without the tunnel being touched. Traffic to that address leaves the local interface while everything else keeps its existing path. The tunnel still carries the default and simply stops being the only candidate for that destination. Prefix length is the only lever the table exposes, and for this job it is enough.

Specificity also rules out the obvious shortcut of excluding a domain name, because the table matches addresses and one name can resolve to several of them. Resolve the host first, then decide which of its addresses deserves the exception.

For everything below, assume a connection called Office, a local gateway of 10.0.0.1 on interface 7, and a destination at 198.51.100.30. Those are placeholders rather than defaults, and the commands above produce the values your machine actually uses. Keep that substitution note with the change so the next reader does not copy the numbers.

Make the route outlive the next reconnect

Windows offers no exclude instruction on a VPN connection, so the exception has to live on the physical interface where the adapter will not rewrite it. The cmdlet that looks like the answer does the opposite: Add-VpnConnectionRoute moves a prefix into the tunnel, which is the mirror case where a split profile should carry one destination and leave the rest local. Reaching for it here guarantees that the traffic you wanted to keep out goes in.

The manual form is a single command. Its weakness is the network change rather than the reconnect.

route -p add 198.51.100.30 mask 255.255.255.255 10.0.0.1 metric 1 if 7

That survives a reboot because of -p and sends one address out of interface 7 while the tunnel carries everything else. Move the laptop to another network and both the gateway and the index go stale, so the entry fails quietly. Record who owns it and when it should be removed.

A connect script is the sturdier version, because it re-adds the exception after every connection instead of hoping the entry survived. The two lines below belong in whatever starts the tunnel, not in a logon script.

rasdial Office
route add 198.51.100.30 mask 255.255.255.255 10.0.0.1 metric 1 if 7

Whatever brings the tunnel up is the right place for the second line, and rasdial only returns once the connection is established, so the route lands behind the adapter's own entries. Run it again after a resume, since a suspend can drop the route and leave the tunnel up. If the task is the reverse one, pushing a single prefix into the tunnel while the rest stays local, then Add-VpnConnectionRoute is the correct tool.

Routing cannot pick a process

Sometimes the requirement is narrower than a destination: one program should take the local path while everything else stays inside the tunnel. Routing cannot express that, because it matches addresses rather than processes. The workable pattern pushes the problem into the launcher.

Keep the profile off the default route and start that single program bound to the local interface address, so the exception becomes the launch command and the tunnel keeps whatever it was already handling. Nothing in the routing table changes, which is why this survives reconnects. It also means the tunnel must not own the default route in the first place, so this is a different design rather than a patch on the previous one.

Its weakness is operational rather than technical. The program must always start through the wrapper, and if the binding is missing after a resume it quietly takes whatever path the table offers. That is tolerable for a browser you open deliberately and unacceptable for anything that must never leave the tunnel.

Per-user connections do not solve this either. Windows can scope a connection to an account while the routing table stays machine-wide, so an account-scoped connection holding a default route still redirects every process on the box, including other sessions. The scope only becomes real when the route scope matches the account. Two people sharing one laptop therefore share one table, and the second inherits whatever tunnel the first one started.

Confirm the exception survived a reconnect

Test the change the way it will fail: disconnect, reconnect, open a fresh application, then request one address that must stay local and one that must use the tunnel. Compare both against Find-NetRoute in the connected state.

If the prefix is missing from the table after a reconnect, it lives in the wrong object rather than in the wrong format. Move it onto the physical interface and repeat the test. Keep both command outputs with the change record, because a snapshot of the working state answers more questions later than a paragraph of explanation. The next person will want to know what connecting produced, not what you intended it to produce.

সম্পৰ্কিত প্ৰবন্ধ