Bearbeiten: Deutlich überarbeitete Antwort aufgrund der aktualisierten Frage.
Dies ist immer noch eine schlechte Idee für ein allgemeines Abmeldeskript - eine Erläuterung der Gründe finden Sie in dieser Frage .
Das Schlüsselargument, das Sie betrachten müssen, ist /MO
. Dies ist der Modifikator. Nach dem Microsoft-Dokument von SCHTASKS wird dann, wenn das /SC
Argument lautet ONEVENT
, /MO
eine XPath-Ereignisabfragezeichenfolge zugelassen.
Dieses Technet-Blog - Erweiterte XML-Filterung in der Windows-Ereignisanzeige - beschreibt das Format und bietet nützliche Beispiele.
Je nachdem, was Sie tatsächlich mit den Daten tun, müssen Sie sie nicht im Kontext der Abmeldung durch den Benutzer ausführen. Dies ist gut, da dadurch die potenzielle Race-Bedingung vermieden wird, die beim Versuch besteht, einen neuen Prozess mitten in einer Abmeldung zu starten. Es vereinfacht auch Ihre XPath-Abfrage:
*[System[EventID=4647]]
Alles, was Sie wirklich tun müssen, ist sicherzustellen, dass die von diesem Ereignis ausgelöste Aufgabe Details über das Ereignis erhält, das das Ereignis ausgelöst hat. Geplante Tasks werden als XML-Dateien gespeichert. Sie können die XML-Datei manuell bearbeiten, um zusätzliche Elemente des XML-Schemas für Taskplaner hinzuzufügen, die nicht über die Benutzeroberfläche verfügbar gemacht werden. Ich empfehle Ihnen, eine Aufgabe zuerst mit SCHTASKS oder über die Benutzeroberfläche mit allen Werten zu erstellen, die Sie angeben können. Dann exportieren Sie es über die Benutzeroberfläche oder mit:
schtasks /Query [/S <system> [/U <username> [/P [<password>]]]] ` /XML /TN <taskname> >event.xml
Der Technet-Artikel Auslösen eines PowerShell-Skripts aus einem Windows-Ereignis bietet eine gute Erklärung und ein Beispiel, wie dies verwendet wird. Das Schlüsselattribut, das sie hinzufügten, war jedoch ValueQueries :
<ValueQueries> <Value name="eventChannel">Event/System/Channel</Value> <Value name="eventRecordID">Event/System/EventRecordID</Value> <Value name="eventSeverity">Event/System/Level</Value> </ValueQueries>
Anstatt die EventRecordID zu verwenden, um das Ereignis wie beschrieben abzurufen, sollten Sie die begrenzten Daten, die Sie benötigen, direkt einlesen können:
<Value name="logoffUsername">Event/EventData/Data[@Name='TargetUserName']</Value>
Vielleicht möchten Sie auch TimeCreated einlesen, da es zuverlässiger sein sollte als eine Zeitfunktion, die in Ihrem Skript aufgerufen wird:
<Value name="eventTime">Event/System/TimeCreated/@SystemTime</Value>
Dies ermöglicht es Ihnen zu verweisen $(logoffUsername)
und (optional) $(eventTime)
in der Powershell - Skript durch die Aufgabe ausgeführt wird .
Falls Sie andere Werte einlesen möchten, ist das Event-XML-Schema auf MSDN definiert . Ich habe auch auf den Blogbeitrag von Michael Albert verwiesen, in dem er Ereignisparameter für Syntaxbeispiele übergeben hat.
Nachdem Sie die Aufgabendefinition geändert haben, können Sie dasselbe XML auf allen Computern importieren :
schtasks /Create [/S <system> [/U <username> [/P [<password>]]]]
/ XML / TN
Hinweis: In der ursprünglichen Frage wurde ein Ereignis für einen Benutzer im Kontext dieses Benutzers erstellt und nur dann ausgeführt, wenn der Benutzer sich abgemeldet hat. Dies ist eine schlechte Idee aufgrund der oben genannten möglichen Rennbedingungen. Dies war die angebotene Lösung.
$cred = Get-Credential $password = $cred.GetNetworkCredential().Password $command = <your command> $myQuery = "*[System[EventID=4647] and EventData[Data [@Name='TargetUserName'] = '" + $env:username + "']]" SCHTASKS /Create /TN "Logoff Monitor" /TR $command /SC ONEVENT ` /RL Highest /RU $cred.Username /RP $password ` /EC ScriptEvents /MO $myQuery