A Windows VPN connection does not store DNS servers in the profile you edit in Settings. When the tunnel comes up, the client negotiates IP configuration with the gateway, the gateway pushes a resolver list, and Windows applies it to the tunnel adapter. That adapter is a separate interface from your Wi-Fi or Ethernet, and the list belongs to the interface, not to the profile. Once you know which object owns the value, overriding it in PowerShell is one command; making the override survive a reconnect is the part that needs a decision.

Which object owns the address

RAS creates the tunnel adapter when the connection succeeds and removes it when the connection drops. The DNS servers you see in ipconfig /all arrive during that configuration exchange, next to the IPv4 and IPv6 addresses and the routes. Because the value is attached to the interface, Set-DnsClientServerAddress writes to something that exists only while the connection does.

That one fact explains most of the confusion around VPN DNS. A profile can be inspected while disconnected, but there is no interface to point at, so a logon script that calls the cmdlet against the VPN alias fails before anyone has connected. It also explains a change that appears to revert: nothing reverted, the interface was destroyed and rebuilt with the values the gateway pushed.

Find the alias before you touch DNS

Profile name and interface alias are usually the same string, but they are not the same object. Get-VpnConnection lists profiles; Get-NetAdapter lists the interfaces Windows actually has. The DNS cmdlets want the second one, and the two diverge more often than people expect, especially when the client appends a descriptor such as "(RAS)" to the adapter name.

If the profile does not exist, PowerShell can create a native entry. The tunnel type and authentication must match what the gateway offers, because a mismatch surfaces at connect time rather than at creation time:

Add-VpnConnection -Name "Corporate" -ServerAddress vpn.example.net `
  -TunnelType Ikev2 -EncryptionLevel Required `
  -AuthenticationMethod Eap -AllUserConnection

Connect once, then read the real alias before writing any DNS command:

rasdial.exe "Corporate"
Get-NetAdapter | Where-Object InterfaceDescription -like "*VPN*"
Get-DnsClientServerAddress -InterfaceAlias "Corporate"

Apply the override in the right order

Order matters more than syntax. The adapter has to be up, the alias has to resolve, and the account has to be allowed to change interface settings. A per-user connection usually accepts the change from the signed-in user; an all-user connection created with -AllUserConnection generally needs an elevated shell.

The cmdlet itself is a one-liner, documented in Microsoft's Set-DnsClientServerAddress reference:

Set-DnsClientServerAddress -InterfaceAlias "Corporate" -ServerAddresses 10.20.0.53,10.20.0.54
Get-DnsClientServerAddress -InterfaceAlias "Corporate" -AddressFamily IPv4

Two failure modes are worth recognising by sight. A wrong alias produces an error from the cmdlet, which is the good outcome, because silence would be worse. A correct cmdlet with no visible effect usually means you are looking at the wrong adapter: a leftover tunnel adapter from another client, a physical NIC with a similar description, or a second virtual adapter created by a sandbox networking tool.

Why a reconnect can undo the change

The override belongs to one interface instance. When the client tears the adapter down and rebuilds it on the next connect, the pushed values are applied again and your list is gone. Some clients recreate the interface on every connect; others reuse it for the life of the session. Compare the interface index in Get-NetAdapter across two connections and you will know which behaviour you have.

Three durable answers exist, and stacking them creates bugs of its own. A connection-specific DNS suffix plus an NRPT rule sends only the internal namespace to the internal resolver and leaves public names alone. A Group Policy or MDM setting applied to the VPN connection sets DNS at connect time with no script involved. A scheduled task that reacts to the connection event and re-runs the cmdlet is the blunt option, but it works and it leaves a log. Pick one owner for DNS and write down which one it is.

Single-label internal names also need a suffix search list. Set-DnsClientGlobalSetting -SuffixSearchList is machine-wide, so it changes resolution for every adapter on the box, including Ethernet. Test it on a lab machine before it goes into an image.

Verify resolution, not just the setting

A resolver listed on an adapter proves only that a value was written. Ask the intended server directly, then ask through the normal path:

Resolve-DnsName server01.corp.example -Server 10.20.0.53
Resolve-DnsName server01.corp.example

The split tells you where the fault sits. Direct query answers and the plain query fails: the adapter setting or the suffix list is not in effect. Both fail: the resolver is unreachable through the tunnel, so look at routes and firewall rules before touching DNS again. Direct query fails while the plain query answers from somewhere else: split DNS is misconfigured and an internal name is being answered by a public resolver, which is a policy problem before it is a connectivity one.

Run the test twice, once right after connect and once after a disconnect and reconnect, and compare the Get-DnsClientServerAddress output from both runs. If the pushed value is back on the second connection, the override lived and died with the adapter, and only the NRPT or policy route from the previous section will hold. Keep both transcripts and the connect timestamps; they settle the does-it-stick question faster than another round of edits.

Related articles