Zum Inhalt springen

WireGuard-Tunnel automatisch je nach Windows-Login (Domain- und lokales Konto) umschalten

20. März 2026 durch
Christian Lisec

Manchmal ist es praktisch, wenn ein WireGuard-Tunnel nicht immer gleich aktiv ist, sondern sich automatisch an den aktuell angemeldeten Windows-User anpasst. Genau das lässt sich mit einem kleinen PowerShell-Skript und der Windows-Aufgabenplanung ziemlich elegant lösen. In meinem Fall entstand die Idee aus einem ganz konkreten Problem: Microsoft Outlook wollte sich mit privaten GMail-Konten nicht verbinden, solange der WireGuard-Tunnel aktiv war. Das passierte sogar trotz Split-Tunneling und statischer Routen. Erst nachdem der Tunnel vollständig deaktiviert wurde, konnte Outlook wieder problemlos per IMAP auf die GMail-Konten zugreifen.

In dieser Anleitung geht es darum, den WireGuard-Tunnel

  • bei einem lokalen Windows-Konto zu deaktivieren
  • bei einem Domain-Konto wieder zu aktivieren

Das Ganze läuft automatisch im Hintergrund, sobald sich ein User anmeldet oder eine Sitzung entsperrt wird.

Die Idee

  1. Windows erkennt, welcher User gerade angemeldet ist
  2. Ein PowerShell-Skript vergleicht diesen User mit einem fest definierten Domain-Account
  3. Je nach Ergebnis wird der WireGuard-Tunnel ein- oder ausgeschaltet

Das PowerShell-Skript

Hier ist das Skript:

# Run as Administrator

# --- CONFIGURATION ---
$targetUser = "DOMAIN\USER"       # User to check
$wgTunnelName = "WG_TUNNEL_NAME"            # WireGuard tunnel name
$wgTunnelPath = "C:\Program Files\WireGuard\Data\Configurations\WG_TUNNEL_NAME.conf.dpapi"  
$wgExePath = "C:\Program Files\WireGuard\wireguard.exe"  # Path to WireGuard

# Uncomment below to log the script events
#$logFile = "C:\WireGuard\WG_Debug.txt"

# --- CHECK CURRENT USER ---
$currentUser = (Get-WmiObject -Class Win32_ComputerSystem).UserName
"$((Get-Date).ToString()) - Detected logged-in user: $currentUser" | Out-File $logFile -Append

#Race condition?
#Start-Sleep -Seconds 10

# --- ENABLE OR DISABLE TUNNEL ---
if ($currentUser -ieq $targetUser) {
   # Enable tunnel if not already enabled
   "$((Get-Date).ToString()) - User matched. Enabling WireGuard." | Out-File $logFile -Append
   & "$wgExePath" /installtunnelservice $wgTunnelPath 2>$null
} else {
   # Disable tunnel if it is enabled
   "$((Get-Date).ToString()) - User did NOT match. Disabling WireGuard." | Out-File $logFile -Append
   & "$wgExePath" /uninstalltunnelservice "$wgTunnelName" 2>$null
}

Was das Skript macht

1. Ziel-User festlegen

Ganz oben wird festgelegt, für welchen Benutzer der Tunnel aktiv sein soll:

$targetUser = "DOMAIN\USER"

Hier kommt also der Domain-Account rein, bei dem WireGuard später aktiv sein soll.

2. WireGuard-Pfade setzen

Danach werden Name und Pfad des Tunnels definiert:

$wgTunnelName = "WG_TUNNEL_NAME"
$wgTunnelPath = "C:\Program Files\WireGuard\Data\Configurations\WG_TUNNEL_NAME.conf.dpapi"
$wgExePath = "C:\Program Files\WireGuard\wireguard.exe"

Wichtig ist, dass diese Werte zu deiner Installation passen.

3. Aktuell angemeldeten User auslesen

Dann holt sich das Skript den aktuell angemeldeten Benutzer:

$currentUser = (Get-WmiObject -Class Win32_ComputerSystem).UserName

Das Ergebnis wird mit dem Ziel-User verglichen.

4. Tunnel aktivieren oder deaktivieren

Wenn der angemeldete User dem Ziel-User entspricht, wird der Tunnel aktiviert:

& "$wgExePath" /installtunnelservice $wgTunnelPath

Passt der User nicht, wird der Tunnel deaktiviert:

& "$wgExePath" /uninstalltunnelservice "$wgTunnelName"

So lässt sich der Tunnel automatisch an den Login anpassen.


Die Aufgabenplanung einrichten

Damit das Skript nicht manuell gestartet werden muss, übernimmt die Windows-Aufgabenplanung den Job.

Die Aufgabe wird bei zwei Ereignissen ausgelöst:

  • Logon
  • Session Unlock

Das bedeutet:

Sobald sich ein User anmeldet oder den Bildschirm wieder entsperrt, läuft das Skript erneut.

Exportierte XML der Aufgabe

Hier die XML-Datei aus der Aufgabenplanung als Referenz:

<Task xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task" version="1.2">
<RegistrationInfo>
<Date>2026-02-19T20:45:38.5559898</Date>
<Author>DOMAIN\USER</Author>
<Description>C:/WireGuard/Wireguard_Toggle_User.ps1</Description>
<URI>\WireGuard Toggle Tunnel By Logged In User</URI>
</RegistrationInfo>
<Triggers>
<LogonTrigger>
<Enabled>true</Enabled>
</LogonTrigger>
<SessionStateChangeTrigger>
<Enabled>true</Enabled>
<StateChange>SessionUnlock</StateChange>
</SessionStateChangeTrigger>
</Triggers>
<Principals>
<Principal id="Author">
<UserId>S-1-5-18</UserId>
<RunLevel>HighestAvailable</RunLevel>
</Principal>
</Principals>
<Settings>
<MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy>
<DisallowStartIfOnBatteries>false</DisallowStartIfOnBatteries>
<StopIfGoingOnBatteries>false</StopIfGoingOnBatteries>
<AllowHardTerminate>true</AllowHardTerminate>
<StartWhenAvailable>false</StartWhenAvailable>
<RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable>
<IdleSettings>
<StopOnIdleEnd>true</StopOnIdleEnd>
<RestartOnIdle>false</RestartOnIdle>
</IdleSettings>
<AllowStartOnDemand>true</AllowStartOnDemand>
<Enabled>true</Enabled>
<Hidden>false</Hidden>
<RunOnlyIfIdle>false</RunOnlyIfIdle>
<WakeToRun>false</WakeToRun>
<ExecutionTimeLimit>PT72H</ExecutionTimeLimit>
<Priority>7</Priority>
</Settings>
<Actions Context="Author">
<Exec>
<Command>powershell.exe</Command>
<Arguments>-WindowStyle Hidden -ExecutionPolicy Bypass -File "C:\WireGuard\Wireguard_Toggle_User.ps1"</Arguments>
</Exec>
</Actions>
</Task>

So ist die Aufgabe aufgebaut

Ein paar Punkte sind hier besonders wichtig:

Trigger

Die Aufgabe startet bei:

  • Benutzeranmeldung
  • Entsperren der Sitzung

Damit reagiert das Skript auch dann, wenn der Benutzer zwischendurch nur kurz gesperrt war.

Ausführung als Systemuser

Der Task läuft als:

<UserId>S-1-5-18</UserId>

Das ist das SYSTEM-Konto. Dadurch hat das Skript die nötigen Rechte, um WireGuard zu steuern.

Unsichtbarer Start

Der PowerShell-Aufruf läuft versteckt:

<Arguments>-WindowStyle Hidden -ExecutionPolicy Bypass -File "C:\WireGuard\Wireguard_Toggle_User.ps1"</Arguments>

So bekommt der Benutzer davon nichts mit.

Kleiner Hinweis zur Zuverlässigkeit

Direkt beim Login kann es manchmal zu einem Timing-Problem kommen. Dann ist der User noch nicht sauber verfügbar, wenn das Skript startet.

In deinem Skript ist dafür schon ein Kommentar vorbereitet:

#Start-Sleep -Seconds 10

Wenn es bei dir mal nicht sofort sauber funktioniert, kann eine kurze Verzögerung helfen.

Außerdem ist Logging vorbereitet:

#$logFile = "C:\WireGuard\WG_Debug.txt"

Das ist super praktisch, wenn du später nachvollziehen willst, was das Skript gerade gemacht hat.

Christian Lisec 20. März 2026
Diesen Beitrag teilen