A Windows VPN profile is a phonebook entry, and PowerShell is one way to edit that entry. Two failures follow from the distinction: a pre-shared key that arrives at the server already corrupted, and a server address that looks updated but is not the one the next tunnel dials. Both are easier to see when you treat the profile as stored state rather than as a command you ran. The walkthrough follows the order the edits happen: create, change, scope, read back.

Build the profile with a literal key

Add-VpnConnection accepts the L2TP pre-shared key through -L2tpPsk. PowerShell processes the string before the cmdlet receives it, and inside double quotes a dollar sign starts a variable reference while a backtick starts an escape. A key that contains either arrives shorter, or with a different character, and the profile is created successfully with the wrong secret.

The failure then appears at IPsec authentication, where the tunnel refuses to come up. That is why a quoting mistake is so often reported as a server-side problem: the profile exists, the name is right, and the secret is quietly wrong.

How you write itWhat PowerShell doesResult
"p@ss$word!42"Expands $word as a variableStored key is truncated
Double-quoted with an escape characterConsumes the next character as an escapeOne character disappears
'p@ss$word!42'Keeps the literal charactersStored key matches the secret

Single quotes are the fix, and they need to wrap the whole value. If the entry already exists with a bad key, -Force replaces it, or remove and recreate the profile and then test with a new connection:

Add-VpnConnection -Name "Contoso-L2TP" -ServerAddress vpn.contoso.example -TunnelType L2tp -L2tpPsk 'n3w$ecret!2026' -AuthenticationMethod Pap -RememberCredential -Force

Keep the real secret out of shell history and shared scripts. Read it from the approved store at runtime and pass the variable rather than the literal, which also avoids the quoting problem entirely.

Change the address, then reconnect

Set-VpnConnection takes space-separated parameters, not assignment syntax. Writing -ServerAddress = "203.0.113.10" passes an extra token, and the cmdlet either errors or stores something you did not intend. The correct form is -Name "Office L2TP" -ServerAddress 203.0.113.10.

Even with the right syntax, the change does not reach a tunnel that is already up. An established connection keeps the address it dialled until it disconnects, so testing the same session proves nothing about the new value. Disconnect, edit, reconnect, and confirm the peer address in the connection details.

Some properties cannot be changed in place. When the cmdlet refuses, note the existing parameters, delete the profile, create it again with the corrected values, and keep the original tunnel and authentication settings. A script that needs to change only the phone number can edit the phonebook entry through the RAS API instead of recreating everything. Whichever route you take, confirm the stored values afterwards rather than trusting the command's silence.

Know which phonebook you edited

A per-user profile lives in that user's network connections directory, and an all-user profile lives in the machine-wide one under the program data tree. They are different entries with different scopes, and editing one leaves the other untouched.

That is why a change can appear to vanish: the script ran as one account, and the test ran as another. Use -AllUserConnection when the profile belongs to the machine, and check the same scope when you read it back.

Read the profile back before you test

Ask Windows what it stored rather than what you passed:

Get-VpnConnection -Name "Office L2TP" | Select-Object Name, ServerAddress, TunnelType, AuthenticationMethod

Compare that output with the intent, then start a fresh connection. If the dial fails, check the RAS client log in Event Viewer before changing the profile again, because the log names the stage that failed.

Keep the authentication design intact while editing. A command that changes the address but drops the certificate or the EAP configuration produces a failure that looks unrelated to the edit, and exporting the working profile first gives you something to restore instead of a guess.

អត្ថបទពាក់ព័ន្ធ