如何在Powershell中创建激活事件的Windows任务


-1

嘿,我需要创建一个Windows任务,其行为很像组策略中的注销脚本(我们的环境没有AD)。该任务需要以登录用户身份运行,以便脚本可以将运行它的用户的名称输出到跟踪用户注销/登录时间和日期的.csv中。我不确定powershell是否是执行此操作的绝对最佳方式,但我需要能够以管理员身份创建任务,但将用户设置为以当前登录用户身份运行脚本,无论当时可能是谁。这将被部署到数百台机器上。

如果还有另一种跟踪用户注销的方法,那么无论是否涉及PowerShell,我都会对该方法非常感兴趣。以前我已经尝试通过编辑注册表来运行脚本以尝试在GP中设置Logoff脚本,但这似乎比我最初预期的更复杂。Zenworks是另一种选择,但它只在用户注销后运行脚本,导致脚本将错误的结果输出到.csv中。

作为参考,下面的链接包含有类似问题但没有我需要定位的某些细节的人。

https://stackoverflow.com/questions/33390035/windows-creating-a-task-for-an-event-from-the-command-line


你的具体问题是什么?你尝试了什么,为什么失败了?
flolilo

@flolilolilo问题主要源于没有AD。如果我有AD,我可以通过GP添加注销脚本。我已经尝试对注册表进行更改,但我缺乏PowerShell脚本的知识,因此很难开发更合理的修复程序。我也尝试使用Zenworks(我们的软件包部署平台)在用户注销事件上运行脚本,但它总是触发太晚(脚本抓取当前登录用户的用户名和其他一些指标并将其放入.csv文件.Zenworks在用户注销后触发脚本。)
nyshanin '17年

Answers:


0

编辑:由于更新的问题,显着修改了答案。
对于通用注销脚本而言,这仍然是一个坏主意 - 请参阅此问题以解释原因。

你需要关注的关键论点是/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

您没有指定这5个响应中的哪一个是相关的。老实说,直到你引用并引用你的答案中的当前相关信息,我认为为你添加报价是不明智的。所以随时改进这个答案,我会为你添加链接。
Ramhound

我只想跟踪Security \ Microsoft Windows安全审核\ 4647。AD在我的环境中不是一件事,我无法获得关于对注册表进行更改的任何答案,以便通过GP添加注销脚本,因此似乎任务是实现我的目标的最合理方式。
nyshanin '17年

@nyshanin AD不需要就位以实现注销脚本。您也可以在本地策略中设置它们。
BryKKan 2010年

@BryKKan有没有办法在很多机器上轻松更改本地策略?
nyshanin '17年

我自己还没有使用它,但不再支持旧版本了,所以我建议看一下这个工具:blogs.technet.microsoft.com/secguide/2016/01/21 / ...
BryKKan

0

在尝试使用taskscheduler完成这项工作之后,我终于得出结论,我最初的想法并不像我原先希望的那样简单可靠地实现。远离任务,但仍保留使用powershell的想法,我制作了一个powershell脚本,zenworks可以在User Logoff运行,以便跟踪我认为相关的细节。该脚本可以在这里找到(由于兼容性问题,它是一个运行批处理文件的powershell脚本):

@@:: This prolog allows a PowerShell script to be embedded in a .CMD file.
@@:: Any non-PowerShell content must be preceeded by "@@"
@@setlocal
@@set POWERSHELL_BAT_ARGS=%*
@@if defined POWERSHELL_BAT_ARGS set POWERSHELL_BAT_ARGS=%POWERSHELL_BAT_ARGS:"=\"%
@@PowerShell -Command Invoke-Expression $('$args=@(^&{$args} %POWERSHELL_BAT_ARGS%);'+[String]::Join([char]10,$((Get-Content '%~f0') -notmatch '^^@@'))) & goto :EOF

if( -Not (Test-Path -Path C:\Windows\Logs\$env:computername.csv ) )
{
New-Item -Path C:\Windows\Logs\ -name "$env:computername.csv" -itemtype "file"
}

$events = Get-WinEvent -FilterHashtable @{LogName='Security'; ID=4647} -MaxEvents 1
foreach ($event in $events)
{
    #Writes events to XML file
    $eventXML = [xml]$event.ToXml()

    #Converts Datetime of event into Two entries
    $DateTime = '{0:MM/dd/yyyy hh:mm:ss}' -f ($event.timecreated)
    $date = ($DateTime -split ' ')[0]
    $time = ($DateTime -split ' ')[1]

    #Formats Outputs of data to prep for export
    $NewLine = "{0},{1},{2},{3},{4}" -f 
    "Logoff",
    $env:computername,
    $eventXML.Event.EventData.Data[1].'#text',
    $Date,
    $Time

    #Exports Data to .csv
    $NewLine | add-content -path C:\Windows\Logs\$env:computername.csv
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.