Importar un perfil VPN en PowerShell con Add-VpnConnection
Add-VpnConnection solo crea perfiles nativos de Windows. Empareje el túnel y la autenticación con la puerta de enlace, fije el alcance a propósito y luego pruebe rutas y DNS.
No existe ningún cmdlet Import-VpnProfile, y el que más se le parece, Add-VpnConnection, nunca lee un archivo .ovpn ni .conf. Compone un perfil nativo de Windows con los parámetros que usted le pasa, y por eso el primer punto de control aquí es el formato del archivo y no la línea de comandos. Si la puerta de enlace habla SSTP, IKEv2, L2TP/IPsec o PPTP, Windows puede poseer el perfil y el resto de la lista se aplica. Si le han dado un archivo de OpenVPN o WireGuard, deténgase en el primer paso: esos clientes tienen sus propios importadores.
Paso 1: Confirme qué perfil puede poseer realmente Windows
Ejecute Get-Command -Module VpnClient en la máquina antes que nada. Windows 10, Windows 11 y Server 2016 o posterior incluyen el módulo; si falta, ningún script copiado hará que este host acepte un perfil nativo. Los cmdlets que importan son Add-VpnConnection, Get-VpnConnection y Remove-VpnConnection, y la lista de parámetros de la referencia de Add-VpnConnection merece una lectura completa.
Nativo significa que la pila VPN de Windows termina el túnel. Eso cubre IKEv2, a menudo con un certificado de máquina; SSTP, que es TLS con autenticación de usuario o certificado dentro; y L2TP/IPsec con una clave precompartida. Un archivo .ovpn es un script de OpenVPN, no una conexión de Windows: lleva directivas como remote, cipher o tls-auth que la pila de Windows no conoce. Un .conf de WireGuard es la misma historia con PrivateKey y AllowedIPs; convertir uno en el otro no es una elección de parámetros sino otra implementación de túnel.
Hay una tercera rama. Si un administrador le entrega un documento XML de VPNv2 CSP o un perfil de Intune, esa es la vía MDM, que aplica la pila de aprovisionamiento y no Add-VpnConnection. No traduzca esos nombres de nodo a parámetros de PowerShell; pregunte qué mecanismo aplica el XML.
Paso 2: Empareje el tipo de túnel con el método de autenticación
-TunnelType y -AuthenticationMethod son parámetros separados, y a la puerta de enlace solo le importa la combinación. Acierte uno y falle el otro y obtendrá un perfil que no conecta con nada, o que se queda colgado con el túnel ya levantado. Establezca ambos de forma explícita en lugar de confiar en un valor predeterminado elegido para otro servicio.
- IKEv2 con MachineCertificate: el cliente presenta un certificado de equipo; establezca también -EncryptionLevel Required.
- SSTP con Eap: primero el túnel TLS, luego PEAP/MSCHAPv2 o un certificado dentro de EAP. Esto necesita el XML del paso 3.
- SSTP, L2TP o PPTP con MSChapv2, Chap o Pap: nombre de usuario y contraseña normales, sin blob EAP.
- L2TP con MSChapv2 y -Lt2pPsk: la PSK cubre la mitad IPsec, el usuario cubre PPP; ambas deben coincidir con el servidor.
Un splat mantiene los valores en un solo sitio:
$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 devuelve el objeto que Windows acaba de escribir, así que puede inspeccionarlo sin una segunda llamada. Si el nombre ya existe, el cmdlet se niega a ejecutarse; -Force lo sobrescribe, que es el reflejo equivocado en un portátil de producción porque descarta en silencio lo que alguien configuró a mano.
Paso 3: Entregue el material de credenciales correctamente
Las contraseñas, las claves precompartidas y los blobs EAP son donde estos scripts suelen romperse. -EapConfigXmlStream quiere un XmlDocument, no una ruta, así que lea y convierta el archivo primero. Pasar una cadena produce un error de conversión que parece un problema de esquema y lleva a la gente a reescribir XML que nunca estuvo mal.
$eap = [xml](Get-Content -Raw .\peap-mschapv2.xml)
Add-VpnConnection -Name "Corp SSTP" -ServerAddress "sstp.example.com" `
-TunnelType Sstp -AuthenticationMethod Eap `
-EapConfigXmlStream $eap -EncryptionLevel RequiredEse XML no es algo que se invente a partir de un fragmento de blog. Nombra el tipo de método EAP y la autenticación interna, y la puerta de enlace compara ambos con su política. Un método interno que no coincide falla después de que el handshake TLS se complete, lo que parece exactamente una contraseña incorrecta y no lo es. Tome el XML de quien opera la puerta de enlace, o expórtelo de un perfil que ya funcione.
En IKEv2 la mitad del certificado es una búsqueda en el almacén. -MachineCertificateIssuerFilter toma un objeto de certificado, y Windows lo usa para encontrar un certificado de cliente utilizable en LocalMachine\My. El certificado necesita una clave privada y una cadena en la que confíe el servidor; cuando falta cualquiera de las dos, la autenticación falla sin detalle útil, así que revise primero el almacén:
Get-ChildItem Cert:\LocalMachine\My |
Where-Object { $_.HasPrivateKey -and $_.NotAfter -gt (Get-Date) } |
Select-Object Subject, Issuer, Thumbprint, NotAfterMantenga los secretos fuera del archivo de script. Una PSK pasada en la línea de comandos o incrustada en un .ps1 acaba en transcripciones, sesiones guardadas y repositorios compartidos, y -RememberCredential almacena las credenciales del usuario para después, convirtiendo una prueba puntual en un permiso permanente.
Paso 4: Decida el alcance antes de la primera ejecución
El mismo cmdlet escribe en dos libretas de teléfono distintas. Sin -AllUserConnection el perfil es suyo y vive en %APPDATA%\Microsoft\Network\Connections\Pbk\rasphone.pbk. Con ella, desde un símbolo del sistema elevado, el perfil va a %ProgramData%\Microsoft\Network\Connections\Pbk\rasphone.pbk y es visible para todas las cuentas, incluida la pantalla de inicio de sesión.
El alcance no es cosmético. Un perfil para todos los usuarios es lo que puede usar una cuenta de servicio, una tarea programada o un escenario previo al inicio de sesión; un perfil por usuario es invisible para los tres. Los objetos también se leen de forma distinta: Get-VpnConnection lista las entradas del usuario actual, Get-VpnConnection -AllUserConnection las de toda la máquina. Elija uno ahora y trate un cambio posterior como borrar y recrear en lugar de editar:
# elevated prompt
Remove-VpnConnection -Name "Corp IKEv2" -Force
Add-VpnConnection -Name "Corp IKEv2" -ServerAddress "vpn.example.com" `
-TunnelType Ikev2 -AuthenticationMethod MachineCertificate `
-EncryptionLevel Required -AllUserConnectionPaso 5: Pruebe qué debe entregar realmente un túnel
Un icono conectado demuestra que el túnel subió y nada más. Conéctese primero desde la línea de comandos para que los fallos lleguen como texto y no como un diálogo, y luego lea lo que Windows registró:
rasdial "Corp IKEv2"
Get-VpnConnection -Name "Corp IKEv2" |
Select-Object Name, ServerAddress, TunnelType, ConnectionStatus, SplitTunneling
Get-NetRoute -DestinationPrefix "0.0.0.0/0"Los dos fallos que los usuarios reportan mientras el estado sigue diciendo Connected son DNS y enrutamiento. Resuelva un nombre interno y compruebe qué servidor respondió; un perfil sin -DnsSuffix puede tunelizar perfectamente y aun así fallar en cada consulta de intranet. Luego mire la ruta predeterminada: con el split tunneling desactivado, la ruta 0.0.0.0/0 de métrica más baja debe apuntar a la interfaz VPN, y con él activado solo los prefijos que espera. Si ambos parecen correctos y el tráfico sigue muriendo, el problema está más allá del perfil, en la política o el filtro de la puerta de enlace.
Cuando la conexión falla del todo, el código acota el paso al que hay que volver:
- 691: la puerta de enlace rechazó las credenciales. Vuelva al paso 3, no al túnel.
- 809: el handshake IKEv2 nunca se completó. Compruebe UDP 500 y 4500, y la confianza en los certificados.
- 789: falta la clave precompartida de L2TP/IPsec o es incorrecta.
- 868: el nombre del servidor no se resolvió. Arregle DNS antes de editar el perfil.
Mantenga el comando que funciona junto a los ajustes que codifica, para que la siguiente persona pueda reconstruir en lugar de hacer ingeniería inversa del perfil desde la interfaz. Si tiene que reconstruir, borre la entrada y vuelva a crearla con los mismos parámetros; parchear un perfil a medio configurar deja rutas y estado de autenticación obsoletos. Y si el archivo nunca fue nativo, vuelva al cliente que lo posee. Un .ovpn disfrazado de perfil IKEv2 no es una importación, es un tique de soporte.