Windows-VPN dauerhaft verbunden halten: rasdial beim Trennungsereignis auslösen
RasClient 20226 und 20227 markieren einen Abbruch; 631 heißt, dass ein Mensch ihn verursacht hat. Lösen Sie rasdial bei den ersten beiden aus, halten Sie einen Anmeldedatensatz bereit und lesen Sie den Exitcode.
Windows bietet für seinen VPN-Client keine Wählrichtlinie, daher ist eine Verbindung, die um Mitternacht abbricht, auch zum Frühstück noch tot. Eine geplante Aufgabe, die den Abbruch beobachtet und rasdial ausführt, schließt diese Lücke ohne einen Client eines Drittanbieters. Ob sich die Aufgabe wie ein Bediener oder wie eine Schleife verhält, hängt an drei Details: welche Ereignisse sie abgleicht, welche Anmeldedaten sie sehen kann und was sie mit dem Ergebnis tut. Keines der drei ist schwierig, und das Fehlen eines einzigen davon erzeugt eine Aufgabe, die ewig wählt.
Warum ein Zeitgeber der falsche Auslöser ist
Ein Zeitgeber wählt nach seinem eigenen Zeitplan, unabhängig davon, ob der Tunnel steht oder nicht. Das erzeugt Versuche, die niemand brauchte, und ein Versuch während einer Arbeitssitzung kann diese unterbrechen. Ein Ereignisauslöser feuert nur, wenn die Verbindung ihren Zustand ändert, was billiger und leichter nachzuvollziehen ist. Das Ereignis trägt auch den Grund, und der Grund ist es, der einen Netzwerkfehler von einer Person trennt, die absichtlich trennt.
Dieser Unterschied ist der Unterschied zwischen einer hilfreichen Aufgabe und einer, die sich jeden Abend mit dem Benutzer streitet. Er ist auch der Teil, der in Rezepten, die nur die Aktion beschreiben, meist fehlt.
Das Ereignispaar und das, das unterdrückt werden muss
Der Client des Remote Access Service schreibt Lebenszyklusdatensätze unter dem Anbieter RasClient in das Application-Protokoll. 20226 markiert eine beendete Verbindung, und 20227 markiert einen fehlgeschlagenen Versuch, sodass beide ein neues Wählen rechtfertigen können. Alles andere in der Aufgabe hängt davon ab, diese beiden Kennungen exakt abzugleichen. Sie sind seit Jahren stabil, weshalb Rezepte, die darauf aufbauen, noch immer kursieren, aber ein Build, der den Anbieter oder die IDs umbenennt, lässt die Abfrage nichts zurückgeben. Wiederholen Sie den Beweisschritt nach jeder Funktionsaktualisierung, statt darauf zu warten, dass die Aufgabe nicht mehr auslöst.
Eine Beendigung muss ausgeschlossen werden. Fehler 631 bedeutet, dass der Benutzer den Port getrennt hat, und ein erneutes Wählen in diesem Moment streitet mit der Person, die gerade absichtlich das Netzwerk gewechselt hat. Legen Sie den Ausschluss in den Auslöserfilter statt in das Skript, damit die Aufgabe gar nicht erst startet. Er darf nur für eine Ereignis-ID gelten, weil ein EventData-Prädikat nur übereinstimmt, wenn das benannte Element existiert, und eine gemeinsame Klausel jedes Ereignis der anderen ID stillschweigend verwerfen würde. Lesen Sie den Elementnamen aus einem echten Datensatz, bevor Sie den Filter schreiben:
Get-WinEvent -LogName Application -MaxEvents 5 -FilterXPath "*[System[Provider[@Name='RasClient'] and EventID=20226]]" | Select-Object -First 1 -ExpandProperty ToXml
Das XML zeigt die genauen Data-Namen in diesem Datensatz. ErrorCode ist die übliche Schreibweise, und ein Datensatz, der etwas anderes verwendet, braucht diesen Namen im Filter unten ersetzt.
<QueryList><Query Id="0" Path="Application"><Select Path="Application">*[System[Provider[@Name='RasClient'] and (EventID=20226 or EventID=20227)]] and (EventData[Data[@Name='ErrorCode'] != '631'] or System[EventID=20227])</Select></Query></QueryList>
Fügen Sie das in den benutzerdefinierten Filter des Auslösers ein und weisen Sie es als Abfrage nach, bevor daraus ein Auslöser wird. Derselbe XPath läuft aus PowerShell gegen das Live-Protokoll, was der billige Weg ist zu sehen, worauf er passt, solange die Aufgabenhistorie noch unbeteiligt ist.
Get-WinEvent -LogName Application -MaxEvents 40 -FilterXPath "*[System[Provider[@Name='RasClient'] and (EventID=20226 or EventID=20227)]] and (EventData[Data[@Name='ErrorCode'] != '631'] or System[EventID=20227])" | Select-Object TimeCreated,Id,Message
Ein Auslöser, der stillschweigend auf nichts passt, sieht genau aus wie eine Aufgabe, die läuft und scheitert. Beide erscheinen als „die Automatisierung funktioniert nicht“, und keiner sagt, welche Hälfte fehlt. Prüfen Sie zuerst die Ausgabe der Abfrage, weil sie die beiden Fälle in einem Schritt trennt.
Das Wählen scheitert, weil niemand da ist, der das Kennwort eintippt
Die Aktion führt rasdial mit dem Verbindungsnamen aus. Wenn das Profil keine zwischengespeicherten Anmeldedaten hat, scheitert das Wählen sofort, weil niemand die Eingabeaufforderung beantworten kann. Das ist der häufigste Grund, warum eine korrekt ausgelöste Aufgabe nichts Sichtbares tut, also prüfen Sie das, bevor Sie den Auslöser anfassen. Das Wählen von Hand aus einer Eingabeaufforderung trennt ein Anmeldedatenproblem von einem Planungsproblem.
Speichern Sie die Anmeldedaten einmal unter dem Konto, unter dem die Aufgabe laufen soll, und machen Sie dieses Konto zum Teil des Entwurfs. Eine Aufgabe, die als SYSTEM läuft, kann keine Anmeldedaten lesen, die Ihr interaktives Konto zwischengespeichert hat, und eine Aufgabe, die als jemand anderes läuft, ebenso wenig. Der Name muss außerdem exakt zum Profil passen, einschließlich eines etwaigen Domänenpräfixes im Benutzerfeld.
rasdial
rasdial "Office VPN"
(Start-Process rasdial -ArgumentList '"Office VPN"' -Wait -PassThru -NoNewWindow).ExitCode
Der erste Befehl listet die Namen auf, die Windows kennt. Der zweite wählt per Namen mit den zwischengespeicherten Anmeldedaten, und der dritte ist die Form, die eine PowerShell-Aktion verwenden sollte, weil sie wartet und einen Wert zurückgibt, den die Aufgabe festhalten kann.
Lesen Sie den Exitcode statt des Fensters
Eine Aufgabe, die einen Prozess ohne Warten startet, meldet Erfolg, sobald der Prozess existiert. Für ein Wählen, das eine Sekunde später scheitern kann, ist dieses Urteil wertlos. Das Warten auf den Exitcode macht die Aktion zu einem echten Ergebnis. Die Aufgabenhistorie allein zeigt nur, dass ein Prozess gestartet ist, nie, dass ein Tunnel hochkam.
Protokollieren Sie den Wert bei jedem Lauf mit einem Zeitstempel. Ein einzelner Fehlschlag nach einem Ausfall ist normal, während drei Fehlschläge in Folge mit demselben Code auf die Anmeldedaten oder das Profil deuten statt auf das Netzwerk. Dieses Muster ist es, was die Historie überhaupt lesenswert macht.
Fügen Sie ein kurzes Wiederholungsintervall als Absicherung hinzu und sagen Sie ausdrücklich, wie es mit einem Ereignisauslöser zusammenspielt. Eine Wiederholung jede Minute für fünf Minuten liefert den zweiten Versuch, wenn das Internet mit dem Tunnel zurückkam, und unter Einstellungen, „Wenn die Aufgabe bereits ausgeführt wird, gilt die folgende Regel“, will die Aufgabe „Keine neue Instanz starten“, damit eine Wiederholung ein noch laufendes Wählen nicht überlappt. Ohne diese Einstellung können zwei rasdial-Prozesse um denselben Port konkurrieren, und der zweite scheitert ohne nützlichen Grund.
Beweisen Sie den Wiederherstellungspfad
Testen Sie beide Richtungen absichtlich. Trennen Sie von Hand und bestätigen Sie, dass kein erneutes Wählen passiert, deaktivieren Sie dann den Netzwerkadapter und bestätigen Sie, dass die Aufgabe auslöst, wenn die Verbindung zurückkehrt. Diese beiden Tests decken die Unterdrückungsregel und den echten Fehlerfall ab, und nichts anderes tut das.
Lesen Sie danach die Aufgabenhistorie statt des Verbindungssymbols. Die Historie zeichnet auf, wann die Aufgabe lief, welches Konto sie verwendete und was die Aktion zurückgab, und das ist der Nachweis, den man braucht, wenn dieselbe Maschine nächsten Monat wieder ausfällt.