The new VPN appeared, authentication worked, and a third-party VPN that had lived on the machine for two years disappeared in the same reboot. Nothing in the deployment log mentioned it, because nothing in the deployment addressed it. The package had replaced the global phone book, and the other connection was an entry in that file. This is a copy operation behaving exactly as a copy operation should.

The fix is not a better copy. It is not copying the file.

What the phone book actually contains

A phone book is a container of connection definitions, not a profile. Per-user entries live under the user profile, and all-user entries live under the machine-wide ProgramData path, which is why a deployment that writes that file touches every local user at once. The same file also carries entries created by other vendors, and that is where the collateral damage comes from.

A connection definition is not the whole story either. Routes, DNS policy, trusted CA material and identity are provisioned by separate owners.

Find which scope owns the profile

List both scopes before writing anything. Get-VpnConnection returns the current user entries and Get-VpnConnection -AllUserConnection returns the machine-wide ones, and the same name can exist in both with different settings. Decide which scope your deployment owns and write it down, because updating the wrong scope leaves the user connecting through the old profile while your change sits in a file nobody reads. A scheduled task running as SYSTEM also sees a different set of profiles than the logged-in user.

Naming the owner is the step that stops the next engineer from repeating the whole-file copy.

Create or update the named connection, nothing else

For a native Windows profile, Add-VpnConnection creates one entry, and -AllUserConnection chooses the machine-wide scope. Run it with -WhatIf first, so the preview lands in your transcript rather than in a user complaint:

Add-VpnConnection -Name 'Office VPN' -ServerAddress 'vpn.example.com' -TunnelType Ikev2 -AuthenticationMethod Eap -EapConfigXmlStream $approvedEapXml -AllUserConnection -WhatIf

The EAP XML has to come from somewhere legitimate: exported from a working reference profile, or generated by your management tooling for the actual gateway. Without correct server-trust settings the profile either connects to the wrong thing or fails everywhere, and neither is a deployment success.

When the entry already exists, compare its settings and update it with Set-VpnConnection instead of deleting and recreating it. Deleting is how a working configuration loses fields nobody documented, and it is how unrelated entries get caught in a broad cleanup.

Check for a second management system that will put the old profile back at the next policy refresh. Pilots fail here more often than at the cmdlet.

Pilot on a machine that already has another VPN

Pick a test machine with an unrelated system-wide entry, deploy, then verify three things: the new profile appears in the intended scope, authentication reaches a private resource, and the unrelated entry still connects. Deploy twice more and confirm the second run changes only the profile it owns. That third check catches a package that is idempotent for its own entry and destructive for everything else.

Removal follows the same rule: Remove-VpnConnection -Name 'Office VPN' -AllUserConnection retires one entry and leaves the rest of the file alone.

Keep the previous intended configuration available, so a scoped rollback means re-importing one profile instead of restoring a whole machine state.

פֿאַרבונדענע אַרטיקלען