Командлета Import-VpnProfile не существует, а та, что кажется ближе всех, Add-VpnConnection, никогда не читает файл .ovpn или .conf. Она собирает собственный профиль Windows из переданных вами параметров, поэтому первая проверка здесь — формат файла, а не командная строка. Если шлюз поддерживает SSTP, IKEv2, L2TP/IPsec или PPTP, Windows может владеть профилем, и остальная часть списка применима. Если вам передали файл OpenVPN или WireGuard, остановитесь на первом шаге: этими импортёрами владеют сами клиенты.

Шаг 1: Убедитесь, что профилем действительно может владеть Windows

Выполните Get-Command -Module VpnClient на машине прежде всего остального. Windows 10, Windows 11 и Server 2016 или более поздние версии поставляют этот модуль; если его нет, никакой скопированный скрипт не заставит этот хост принять собственный профиль. Важны командлеты Add-VpnConnection, Get-VpnConnection и Remove-VpnConnection, а список параметров в справочнике Add-VpnConnection стоит прочитать один раз целиком.

Собственный означает, что туннель завершает VPN-стек Windows. Это охватывает IKEv2, часто с сертификатом компьютера; SSTP, то есть TLS с проверкой подлинности пользователя или сертификата внутри; и L2TP/IPsec с общим предварительным ключом. Файл .ovpn — это скрипт OpenVPN, а не подключение Windows: он несёт директивы вроде remote, cipher или tls-auth, о которых стек Windows не имеет представления. Файл .conf WireGuard — та же история с PrivateKey и AllowedIPs; преобразовать одно в другое — не выбор параметра, а другая реализация туннеля.

Есть и третья ветка. Если администратор передаёт вам XML-документ VPNv2 CSP или профиль Intune, это путь MDM, применяемый стеком подготовки, а не Add-VpnConnection. Не переводите имена этих узлов в параметры PowerShell; вместо этого спросите, какой механизм применяет этот XML.

Шаг 2: Сочетайте тип туннеля с методом проверки подлинности

-TunnelType и -AuthenticationMethod — отдельные параметры, и шлюз заботит только их сочетание. Правильно задайте одно и ошибитесь с другим — получите профиль, который никуда не подключается, или зависает, когда туннель уже поднят. Задавайте оба явно, вместо того чтобы доверять значению по умолчанию, выбранному для другого сервиса.

  • IKEv2 с MachineCertificate: клиент предъявляет сертификат компьютера; также задайте -EncryptionLevel Required.
  • SSTP с Eap: сначала туннель TLS, затем PEAP/MSCHAPv2 или сертификат внутри EAP. Это требует XML из шага 3.
  • SSTP, L2TP или PPTP с MSChapv2, Chap или Pap: обычные имя пользователя и пароль, без EAP-блока.
  • L2TP с MSChapv2 и -Lt2pPsk: PSK закрывает половину IPsec, пользователь закрывает PPP; оба должны совпадать с сервером.

Хэш-таблица (splat) держит значения в одном месте:

$p = @{
  Name                 = "Corp IKEv2"
  ServerAddress        = "vpn.example.com"
  TunnelType           = "Ikev2"
  AuthenticationMethod = "MachineCertificate"
  EncryptionLevel      = "Required"
  SplitTunneling       = $false
  DnsSuffix            = "corp.example.com"
}
Add-VpnConnection @p -PassThru

-PassThru возвращает объект, который Windows только что записал, так что его можно изучить без второго вызова. Если имя уже существует, командлет отказывается работать; -Force перезаписывает его, что является неверным рефлексом на рабочем ноутбуке, потому что молча отбрасывает всё, что кто-то настроил вручную.

Шаг 3: Передайте материал учётных данных правильно

Пароли, общие предварительные ключи и EAP-блоки — вот где эти скрипты обычно ломаются. -EapConfigXmlStream хочет XmlDocument, а не путь, поэтому сначала прочитайте и приведите файл. Передача строки даёт ошибку преобразования, которая читается как проблема схемы и заставляет людей переписывать XML, который никогда не был неправильным.

$eap = [xml](Get-Content -Raw .\peap-mschapv2.xml)
Add-VpnConnection -Name "Corp SSTP" -ServerAddress "sstp.example.com" `
  -TunnelType Sstp -AuthenticationMethod Eap `
  -EapConfigXmlStream $eap -EncryptionLevel Required

Этот XML не стоит выдумывать из фрагмента блога. Он называет тип метода EAP и внутреннюю проверку подлинности, и шлюз сравнивает оба со своей политикой. Несовпадающий внутренний метод терпит неудачу после завершения рукопожатия TLS, что выглядит точно как неверный пароль, но им не является. Берите XML у того, кто управляет шлюзом, или экспортируйте его из профиля, который уже работает.

Для IKEv2 сертификатная половина — это поиск в хранилище. -MachineCertificateIssuerFilter принимает объект сертификата, и Windows использует его, чтобы найти подходящий клиентский сертификат в LocalMachine\My. Сертификату нужен закрытый ключ и цепочка, которой доверяет сервер; когда чего-то из этого нет, проверка подлинности терпит неудачу без полезных подробностей, поэтому сначала проверьте хранилище:

Get-ChildItem Cert:\LocalMachine\My |
  Where-Object { $_.HasPrivateKey -and $_.NotAfter -gt (Get-Date) } |
  Select-Object Subject, Issuer, Thumbprint, NotAfter

Держите секреты вне файла скрипта. PSK, переданный в командной строке или зашитый в .ps1, попадает в стенограммы, сохранённые сеансы и общие репозитории, а -RememberCredential кэширует учётные данные пользователя на будущее, превращая разовый тест в постоянное разрешение.

Шаг 4: Определите область до первого запуска

Тот же командлет пишет в две разные телефонные книги. Без -AllUserConnection профиль принадлежит вам и живёт в %APPDATA%\Microsoft\Network\Connections\Pbk\rasphone.pbk. С ним, из командной строки с повышенными правами, профиль попадает в %ProgramData%\Microsoft\Network\Connections\Pbk\rasphone.pbk и виден каждой учётной записи, включая экран входа.

Область — это не косметика. Профиль для всех пользователей — это то, что может использовать служебная учётная запись, запланированная задача или сценарий до входа в систему; профиль для одного пользователя невидим всем трём. Объекты читаются тоже по-разному: Get-VpnConnection перечисляет записи текущего пользователя, Get-VpnConnection -AllUserConnection перечисляет общие для машины. Выберите одно сейчас, а более позднее изменение считайте удалением и повторным созданием, а не правкой:

# elevated prompt
Remove-VpnConnection -Name "Corp IKEv2" -Force
Add-VpnConnection -Name "Corp IKEv2" -ServerAddress "vpn.example.com" `
  -TunnelType Ikev2 -AuthenticationMethod MachineCertificate `
  -EncryptionLevel Required -AllUserConnection

Шаг 5: Проверьте, что туннель действительно должен доставлять

Значок подключения доказывает, что туннель поднялся, и больше ничего. Сначала подключитесь из командной строки, чтобы сбои приходили текстом, а не диалогом, затем прочитайте, что записала Windows:

rasdial "Corp IKEv2"
Get-VpnConnection -Name "Corp IKEv2" |
  Select-Object Name, ServerAddress, TunnelType, ConnectionStatus, SplitTunneling
Get-NetRoute -DestinationPrefix "0.0.0.0/0"

Две неисправности, о которых сообщают пользователи, пока статус всё ещё показывает Connected, — это DNS и маршрутизация. Разрешите внутреннее имя и проверьте, какой сервер ответил; профиль без -DnsSuffix может прекрасно строить туннель и всё равно проваливать каждый поиск в интранете. Затем посмотрите на маршрут по умолчанию: при выключенном раздельном туннелировании маршрут 0.0.0.0/0 с наименьшей метрикой должен указывать в интерфейс VPN, а при включённом — только ожидаемые вами префиксы. Если оба выглядят правильно, а трафик всё равно умирает, проблема за пределами профиля — в политике или фильтре шлюза.

Когда подключение полностью не удаётся, код сужает шаг, к которому надо вернуться:

  • 691: шлюз отклонил учётные данные. Вернитесь к шагу 3, а не к туннелю.
  • 809: рукопожатие IKEv2 так и не завершилось. Проверьте UDP 500 и 4500, а также доверие к сертификату.
  • 789: общий предварительный ключ L2TP/IPsec отсутствует или неверен.
  • 868: имя сервера не разрешилось. Исправьте DNS, прежде чем править профиль.

Держите рабочую команду рядом с настройками, которые она кодирует, чтобы следующий человек мог пересобрать, а не реконструировать профиль из интерфейса. Если пересобрать всё же придётся, удалите запись и создайте её заново из тех же параметров; правка наполовину настроенного профиля оставляет после себя устаревшие маршруты и состояние проверки подлинности. А если файл никогда не был собственным, вернитесь к клиенту, которому он принадлежит. Файл .ovpn, переодетый в профиль IKEv2, — это не импорт, а заявка в поддержку.

Похожие статьи