This PowerShell automation script simplifies connecting to the HTWG Konstanz VPN using OpenVPN with MFA (OTP). It uses Python to generate your one-time password (OTP), combines it with your credentials, and launches the VPN connection, all in a single step.
The current version stores the password and user as env variable on the system. This is considered not safe. Use this script on one's own responsibility. Feel free to implement an own version with a secured password-manager.
vpn-connect
├── vpn.ps1 # Main PowerShell script to connect to VPN
├── getotp.py # Python script that generates OTP using pyotp
├── HTWG-MFA-WS2526-STUD.ovpn # Your OpenVPN config file
└── .gitignore
-
Python 3.x (added to PATH)
- Install dependency:
pip install pyotp
- Install dependency:
-
OpenVPN Community Edition (open-source) Do not use the “OpenVPN Connect” GUI app, it doesn’t support CLI usage. Instead use the CommunityEdition
-
PowerShell 5.1+ (PowerShell 7.x recommended)
-
Administrator privileges (required for OpenVPN)
-
Working
.ovpnfile (downloadable from the HTWG VPN Setup Page) -
The QR code from HTWG IT support or the authenticator app (to obtain the TOTP secret)
The getotp.py script generates the One-Time Password (OTP) used for HTWG’s MFA-protected VPN login.
It reads the TOTP secret from the environment variable HTWG_TOTP_SECRET.
import pyotp
import os
secret = os.getenv("HTWG_TOTP_SECRET")
totp = pyotp.TOTP(secret)
otp = totp.now()
print(otp)The script prints the current 6-digit code to stdout, the PowerShell script then appends that code to your VPN password automatically.
If you don’t yet have your TOTP secret (the base32 key usually embedded in the QR code), you can extract it using this open-source tool: https://github.com/scito/extract_otp_secrets
Once extracted, store your secret securely as an environment variable (example below).
You can provide credentials via environment variables (recommended) or via a local file.
Set them in PowerShell before running the script:
$env:VPN_USER = "your_username"
$env:VPN_PASS = "your_password"
$env:HTWG_TOTP_SECRET = "your_totp_secret"
# Run the script
.\vpn.ps1To make them persistent (not secure for secrets, use with caution):
[Environment]::SetEnvironmentVariable("VPN_USER", "your_username", "User")
[Environment]::SetEnvironmentVariable("VPN_PASS", "your_password", "User")
[Environment]::SetEnvironmentVariable("HTWG_TOTP_SECRET", "YOUR_SECRET_KEY", "User")
# Restart PowerShell after setting permanentlyAdjust paths at the top of vpn.ps1 as needed:
$script:pathToOpenvpnExe = "C:\Program Files\OpenVPN\bin\openvpn.exe"
$script:pathToPython = "python.exe"
$script:pathToConfigFile = "$script:workingDir\HTWG-MFA-WS2526-STUD.ovpn"If you prefer to start the VPN with a double-click, create a small .bat launcher:
@echo off
powershell -Command "Start-Process powershell -ArgumentList '-NoProfile -ExecutionPolicy Bypass -File \"C:\Path\to\connecttoovpntest.ps1\"' -Verb RunAs"Save this file as connect_vpn.bat and adjust the path to your .ps1. When double-clicked, it will open PowerShell as Administrator, bypass execution policy restrictions, and run the main script.
- Missing OTP? Check that
HTWG_TOTP_SECRETis set and correct. Rungetotp.pymanually to verify it prints a 6-digit code. - Empty credentials when elevated? When PowerShell elevates to admin, user environment variables may not be inherited. Either set the variables as persistent for the User scope (see above) or place them in a local
credentials.ps1that the script imports after elevation. - Check logs: Review
vpn_log.txtin the working directory for detailed error messages.
This project is licensed under the MIT License. See the LICENSE file for details.