Skip to main content

How to Connect to and Disconnect from a VPN in Batch Script

Manually clicking through Windows network menus every time you need to access a secure resource is inefficient. For developers and system administrators, automating these connections ensures that secure tunnels are active only when needed, reducing exposure and saving time. Whether you need to connect to a company network to run a backup or disconnect after a secure upload, the native Windows command line provides a simple, direct interface for VPN management.

This guide will explain how to use the rasdial command to connect to and disconnect from your VPN profiles using a Batch script.

The Tool: RASDIAL

The rasdial utility is the standard command-line interface for Remote Access Service (RAS) connections in Windows. It works with all built-in Windows VPN types (PPTP, L2TP, IKEv2) and dial-up profiles. The command name rasdial, the parameter /disconnect, and the error codes are language-independent, they work the same way on every Windows display language.

Basic Connection Syntax

To connect to a saved VPN profile, use the following format:

rasdial "VPN_PROFILE_NAME" "USERNAME" "PASSWORD"

If credentials are already saved in the Windows VPN settings (via the "Remember my credentials" checkbox), you can omit the username and password:

rasdial "VPN_PROFILE_NAME"

Basic Disconnection Syntax

To drop the connection, add the /disconnect flag:

rasdial "VPN_PROFILE_NAME" /disconnect
warning

Credential Security. Including your password in clear text inside a .bat file is a major security risk. Anyone who can read the file has your VPN credentials. If you have saved the credentials in the Windows VPN settings, omit the username and password from the script entirely. For automated scenarios, use the Windows Credential Manager (cmdkey) to store credentials securely.

Method 1: Connecting to a Saved VPN Profile

A professional script should verify the VPN profile exists, check if already connected, attempt the connection, wait for the network to stabilize, and verify that the tunnel is actually working.

@echo off
setlocal enabledelayedexpansion

set "VPN_Name=WorkVPN"

echo [VPN] Preparing to connect to "%VPN_Name%"...

rem --- Check if the VPN profile exists ---
rem --- "rasphone -h" is not available; instead, try checking via rasdial output ---
rem --- or verify through the phonebook file ---

rem --- Check if already connected ---
rasdial 2>nul | findstr /i /c:"%VPN_Name%" >nul 2>&1
if %errorlevel% equ 0 (
echo [INFO] Already connected to "%VPN_Name%". No action needed.
endlocal
pause
exit /b 0
)

rem --- Attempt connection using saved credentials ---
echo [VPN] Connecting to "%VPN_Name%"...
rasdial "%VPN_Name%"

if %errorlevel% neq 0 (
echo [ERROR] Failed to connect to "%VPN_Name%".
echo [INFO] Common causes:
echo - Profile name does not match. Check: ncpa.cpl
echo - Saved credentials are expired or missing.
echo - The VPN server is unreachable.
echo - Error 864: A connection already exists or policy restriction.
endlocal
pause
exit /b 1
)

echo [SUCCESS] VPN connection command accepted.
echo [INFO] Waiting for IP assignment and route configuration...

rem --- Wait for the virtual adapter to receive its IP and update routing ---
timeout /t 8 /nobreak >nul

rem --- Verify the connection is actually active ---
rasdial 2>nul | findstr /i /c:"%VPN_Name%" >nul 2>&1
if %errorlevel% equ 0 (
echo [OK] "%VPN_Name%" is active.
) else (
echo [WARN] Connection may have dropped immediately after connecting.
echo [WARN] Check VPN server logs or try connecting manually.
)

endlocal
pause

Key improvements:

  1. Pre-connection check: The script checks if the VPN is already active before attempting to connect. Connecting twice can trigger Error 864 or authentication errors on some servers.
  2. Post-connection wait: rasdial returns success when the dial-up handshake completes, but the virtual network adapter still needs several seconds to receive an IP address and update the routing table. The 8-second wait prevents subsequent network commands from failing.
  3. Post-connection verification: After waiting, the script confirms the VPN still appears in the active connections list. Some VPNs connect briefly and then disconnect due to policy mismatches or server-side rejections.
  4. No clear-text password: The script relies on saved credentials, avoiding the security risk of embedding passwords in the file.

Method 2: Disconnecting from a Specific VPN

@echo off
setlocal

set "VPN_Name=WorkVPN"

rem --- Check if the VPN is actually connected before trying to disconnect ---
rasdial 2>nul | findstr /i /c:"%VPN_Name%" >nul 2>&1
if %errorlevel% neq 0 (
echo [INFO] "%VPN_Name%" is not currently connected. Nothing to disconnect.
endlocal
pause
exit /b 0
)

echo [VPN] Disconnecting from "%VPN_Name%"...

rasdial "%VPN_Name%" /disconnect

if %errorlevel% equ 0 (
echo [SUCCESS] "%VPN_Name%" has been disconnected.
) else (
echo [ERROR] Failed to disconnect "%VPN_Name%".
)

endlocal
pause

Method 3: Disconnecting All Active VPN Connections

If you want to clean up all active dial-up and VPN sessions at once, you can iterate through the rasdial output. The script had a flaw: rasdial (with no arguments) lists active connections, but its output includes header and footer lines that are not connection names. These lines are language-dependent and must be filtered out.

The Problem with Parsing rasdial Output

Running rasdial with no arguments produces output like this (English):

Connected to
WorkVPN
Office_VPN
Command completed successfully.

On non-English Windows, the header ("Connected to") and footer ("Command completed successfully.") are translated. The connection names themselves are not translated: they are whatever the user named the profile.

Robust Disconnect-All Script

@echo off
setlocal enabledelayedexpansion

echo [VPN] Checking for active connections...

rem --- Run rasdial to get the list of active connections ---
rem --- Skip the first line (header: "Connected to" or its translation) ---
rem --- Filter out blank lines and the footer line ---

set "DisconnectCount=0"
set "ConnectionFound=0"

for /f "skip=1 tokens=*" %%a in ('rasdial 2^>nul') do (
set "Line=%%a"

rem --- Skip empty lines ---
if defined Line (
rem --- The footer line typically contains a period at the end ---
rem --- Connection names almost never end with a period ---
rem --- Also check: if rasdial shows no connections, the output is different ---

rem --- Try to disconnect this line as if it were a connection name ---
rem --- If it is the footer text, rasdial /disconnect will fail harmlessly ---
rasdial "%%a" /disconnect >nul 2>&1
if !errorlevel! equ 0 (
echo [OK] Disconnected: %%a
set /a DisconnectCount+=1
)
)
)

if !DisconnectCount! equ 0 (
echo [INFO] No active VPN connections found.
) else (
echo [SUCCESS] !DisconnectCount! connection^(s^) disconnected.
)

endlocal
pause

How this handles the language problem: Instead of trying to identify and skip the translated footer line by matching specific text, the script simply attempts to disconnect every line. If the line is the footer text (e.g., "Command completed successfully." or its translation), the rasdial "footer text" /disconnect command fails silently because no connection with that name exists. Only real connection names produce a successful disconnect. This approach is inherently language-independent.

Method 4: Connect, Perform Task, Disconnect

A common pattern is to connect to a VPN, perform a secure operation, and then immediately disconnect to minimize exposure time.

@echo off
setlocal

set "VPN_Name=WorkVPN"
set "ServerShare=\\10.0.0.5\SecureData"
set "DriveLetter=Z:"

rem --- Connect ---
echo [VPN] Connecting to "%VPN_Name%"...

rasdial 2>nul | findstr /i /c:"%VPN_Name%" >nul 2>&1
if %errorlevel% equ 0 (
echo [INFO] Already connected.
) else (
rasdial "%VPN_Name%"
if %errorlevel% neq 0 (
echo [ERROR] VPN connection failed.
endlocal
pause
exit /b 1
)
echo [INFO] Waiting for network stabilization...
timeout /t 8 /nobreak >nul
)

rem --- Verify connectivity through the tunnel ---
ping -n 1 -w 2000 10.0.0.5 >nul 2>&1
if %errorlevel% neq 0 (
echo [ERROR] Cannot reach the server through the VPN tunnel.
echo [INFO] Disconnecting...
rasdial "%VPN_Name%" /disconnect >nul 2>&1
endlocal
pause
exit /b 1
)

rem --- Perform the secure task ---
echo [TASK] Mapping network drive %DriveLetter% to %ServerShare%...
net use %DriveLetter% /delete >nul 2>&1
net use %DriveLetter% %ServerShare% /persistent:no >nul 2>&1

if %errorlevel% equ 0 (
echo [SUCCESS] Drive mapped. Perform your file operations now.
echo.
echo Press any key when finished to disconnect the VPN...
pause >nul
net use %DriveLetter% /delete >nul 2>&1
) else (
echo [ERROR] Failed to map network drive.
)

rem --- Disconnect ---
echo [VPN] Disconnecting from "%VPN_Name%"...
rasdial "%VPN_Name%" /disconnect

if %errorlevel% equ 0 (
echo [SUCCESS] VPN disconnected. Secure session ended.
) else (
echo [WARN] Disconnect command may have failed. Verify manually.
)

endlocal
pause

Security note: This script does not include any credentials in the file. The net use command in the original article contained a clear-text password (pass123). The fixed version uses /persistent:no and relies on Windows prompting for credentials or using saved credentials from the Credential Manager.

How to Avoid Common Errors

Wrong Way: Using the Wrong Profile Name

The profile name must match exactly what appears in Windows Network Connections. A missing space or wrong capitalization will cause a failure.

rem *** BAD: name mismatch (missing space) ***
rasdial OfficeVPN

Correct Way: Open ncpa.cpl (Network Connections), find your VPN entry, and copy the name exactly. Always wrap it in quotes to handle spaces.

rem *** GOOD: exact name with quotes ***
rasdial "Office VPN"

Wrong Way: Embedding Passwords in the Script File

rem *** BAD: password visible to anyone who can read the file ***
rasdial "WorkVPN" "admin" "P@ssw0rd123"

Correct Way: Save credentials through the Windows VPN settings UI ("Remember my credentials") or use the Windows Credential Manager.

rem --- Store credentials securely (run once) ---
cmdkey /add:"VPNServerAddress" /user:"domain\username" /pass:"password"

rem --- Connect without exposing credentials in the script ---
rasdial "WorkVPN"

Wrong Way: Running Network Commands Immediately After Connection

rasdial returns success when the authentication handshake completes, but the virtual adapter still needs time to receive an IP address and update the routing table.

rem *** BAD: ping runs before the VPN adapter has an IP ***
rasdial "WorkVPN"
ping 10.0.0.5

Correct Way: Wait for the network to stabilize, then verify connectivity.

rasdial "WorkVPN"
timeout /t 8 /nobreak >nul
ping -n 1 -w 2000 10.0.0.5 >nul 2>&1
if %errorlevel% equ 0 echo [OK] Server reachable.

Wrong Way: Connecting Without Checking Current State

Attempting to connect when already connected can trigger Error 864 or duplicate authentication attempts.

rem *** BAD: may cause Error 864 if already connected ***
rasdial "WorkVPN"

Correct Way: Check first.

rasdial 2>nul | findstr /i /c:"WorkVPN" >nul 2>&1
if %errorlevel% equ 0 (
echo Already connected.
) else (
rasdial "WorkVPN"
)

Common RASDIAL Error Codes

Error CodeMeaningCommon Solution
691Authentication failureCheck username/password or update saved credentials
800VPN tunnel could not be establishedCheck server address, firewall, and internet connectivity
812Connection prevented by RAS/VPN server policyContact the VPN administrator
864Connection already exists or policy restrictionCheck if already connected; disconnect first

Best Practices and Rules

1. Use Saved Credentials or Credential Manager

Never store passwords in Batch files. Use the Windows "Remember my credentials" option or cmdkey to store credentials in the encrypted Windows vault.

2. Wait for IP Assignment After Connecting

Allow 5–10 seconds after rasdial returns before running any network commands. The virtual adapter needs time to receive an IP address and update the routing table.

3. Check Connection State Before Acting

Always verify whether the VPN is already connected before attempting to connect, and verify it is connected before attempting to disconnect. This prevents errors and duplicate sessions.

4. The rasdial Command Is Language-Independent

The command name, parameters (/disconnect), and error codes are identical across all Windows display languages. Only the descriptive output text ("Connected to", "Command completed successfully") is translated. Connection profile names are user-defined and never translated.

5. Use setlocal / endlocal

Always wrap scripts in setlocal and endlocal to prevent variables from leaking into the parent environment.

6. Minimize Connection Duration

Connect to the VPN only when needed and disconnect immediately after the task completes. This follows the principle of least privilege and reduces the attack surface.

Final Thoughts

Connecting to and disconnecting from a VPN via Batch script is a fundamental automation skill for system administrators. The rasdial command is simple, language-independent, and works with all built-in Windows VPN types. The critical points are: always check connection state before connecting or disconnecting, never embed passwords in script files, always wait for network stabilization after connecting, and verify the tunnel is functional before running dependent tasks. With these safeguards, you can integrate secure VPN connectivity directly into your backup routines, deployment scripts, and maintenance automation.