编辑:由于更新的问题,显着修改了答案。
对于通用注销脚本而言,这仍然是一个坏主意 - 请参阅此问题以解释原因。
你需要关注的关键论点是/MO
。这是修饰符。根据SCHTASKS的Microsoft文档,当/SC
参数为ONEVENT
,则/MO
允许XPath事件查询字符串。
此Technet博客 -
Windows事件查看器中的高级XML过滤 - 描述了格式并提供了有用的示例。
根据您实际使用的数据,您实际上不需要在用户注销的上下文中执行。这很好,因为它避免了在注销过程中尝试启动新进程所固有的潜在竞争条件。它还简化了您的XPath查询:
*[System[EventID=4647]]
您真正需要做的就是确保从此事件触发的任务接收有关触发它的事件的详细信息。计划任务存储为xml文件,您可以手动编辑XML以添加未通过UI公开的任务计划程序XML架构的其他元素。我建议您首先使用SCHTASKS或通过UI创建一个任务,其中包含您可以指定的所有值。然后通过UI或使用以下方式导出:
schtasks /Query [/S <system> [/U <username> [/P [<password>]]]] `
/XML /TN <taskname> >event.xml
Technet文章从Windows事件触发PowerShell脚本提供了一个很好的解释和如何使用它的示例。但是,他们添加的关键属性是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脚本中。
如果您想要引入其他值,则在MSDN上定义事件XML架构。我还引用了Michael Albert关于传递语法示例的事件参数的博客文章。
完成任务定义的修改后,可以在所有计算机上导入相同的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