Изменить: Значительно пересмотренный ответ из-за обновленного вопроса.
Это все еще плохая идея для сценария выхода из системы общего назначения - см. Этот вопрос для объяснения причин.
Ключевым аргументом, на который вам нужно обратить внимание, является /MO
. Это модификатор. Согласно документу Microsoft SCHTASKS, когда аргумент /SC
равен ONEVENT
, тогда /MO
разрешает строку запроса события XPath.
Этот блог Technet - Расширенная фильтрация XML в средстве просмотра событий Windows - описывает формат и предоставляет полезные примеры.
Исходя из того, что вы на самом деле делаете с данными, вам не нужно выполнять их в контексте выхода пользователя из системы. Это хорошо, поскольку позволяет избежать потенциального состояния гонки, присущего попытке запуска нового процесса в середине выхода из системы. Это также упрощает ваш запрос XPath:
*[System[EventID=4647]]
Все, что вам действительно нужно сделать, - это убедиться, что задание, запущенное из этого события, получит подробную информацию о событии, которое его вызвало. Запланированные задачи хранятся в виде XML-файлов, и вы можете вручную редактировать XML-файл, добавляя дополнительные элементы XML-схемы планировщика задач, которые не отображаются через пользовательский интерфейс. Я предлагаю вам сначала создать задачу с помощью SCHTASKS или через пользовательский интерфейс со всеми значениями, которые вы можете указать. Затем экспортируйте его через пользовательский интерфейс или с помощью:
schtasks /Query [/S <system> [/U <username> [/P [<password>]]]] `
/XML /TN <taskname> >event.xml
Статья Technet Запуск сценария PowerShell из события Windows предлагает хорошее объяснение и пример того, как его использовать. Однако ключевым атрибутом, который они добавили, был ValueQueries:
<ValueQueries>
<Value name="eventChannel">Event/System/Channel</Value>
<Value name="eventRecordID">Event/System/EventRecordID</Value>
<Value name="eventSeverity">Event/System/Level</Value>
</ValueQueries>
Вместо того чтобы использовать EventRecordID для запроса обратно к событию, как они продемонстрировали, вы должны быть в состоянии получить ограниченные данные, которые вам нужны напрямую:
<Value name="logoffUsername">Event/EventData/Data[@Name='TargetUserName']</Value>
Вы также можете использовать TimeCreated, так как он должен быть более надежным, чем функция времени, вызываемая из вашего скрипта:
<Value name="eventTime">Event/System/TimeCreated/@SystemTime</Value>
Это позволит вам ссылаться на $(logoffUsername)
и (необязательно) $(eventTime)
в скрипте Powershell, выполняемом задачей.
Если вы хотите получить другие значения, XML-схема события определяется в MSDN. Я также сослался на сообщение в блоге Майкла Альберта о передаче параметров событий для примеров синтаксиса.
Закончив изменение определения задачи, вы можете импортировать один и тот же XML-файл на все компьютеры:
schtasks /Create [/S <system> [/U <username> [/P [<password>]]]]
/XML /TN
Примечание. Исходный вопрос предусматривал создание события для пользователя в контексте этого пользователя и запуск его только после выхода пользователя из системы. Это плохая идея из-за потенциального состояния гонки, упомянутого выше. Для справки, это было предложенное решение.
$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