Windows Server 2008 R2
我正在尝试使用 PowerShell 获取过去一天内登录过远程桌面服务(以前称为终端服务)的用户列表。经过一点点理解和大量复制和粘贴,我得到了这个小脚本:
$a = (Get-Date).AddDays(-1)
Get-EventLog -LogName Security -after $a | Where-Object {($_.EventID -eq '4624') -and $_.EntryType -eq 'SuccessAudit') -and ($_.Message | Select-String "Logon Type:\t\t\t10")}
默认输出告诉我事情已经发生以及发生的时间,这是一个好的开始。我想真的类似的做法是同时显示用户。真不知道如何获取用户和/或如何显示它。
这是我的问题:如何添加与该事件 ID 4624 / 登录类型 10 事件关联的用户名?理想情况下,我只想显示登录时间和用户名。
答案1
首先,我建议使用Get-WinEvent
并传递哈希来尽可能多地进行过滤(从而避免创建大量Where-Object
将被丢弃的对象):
Get-WinEvent -filterHashtable @{LogName='Security'; StartTime=$a; Id=4624; Level=0}
0级为成功审计。可以使用参数远程执行此操作-computer
。然后过滤结果以获取登录类型:
... | Where-Object { $_.Message -match 'Logon Type:\s+10'}
使用正则表达式避免对空格进行硬编码。
从消息中提取用户和域会有点麻烦,因为有两个“帐户名称”值:一个用于计算机,一个用于用户。但插入(可本地化)消息文本的所有可替换值都在事件的 Properties 属性中,因此需要使用示例1进行一些检查以查看索引
... | Select-Object *, @{l='LogonAccount';e={$_.Properties[6].Value + "\" + $_.Properties[5].Value }}
显然,捕获其他详细信息(例如 SID、客户端 IP)遵循相同的模式。
因此:
Get-WinEvent -filterHashtable @{LogName='Security'; StartTime=$a; Id=4624; Level=0} |
Where-Object { $_.Properties[8].Value -eq 10} |
Select-Object *, @{l='LogonAccount';e={$_.Properties[6].Value + "\" + $_.Properties[5].Value }}
1对于单个事件,$ev
我使用了:
0..($ev.Properties.Count-1) | Select @{l='Idx';e={$_}},@{l='Property';e={$ev.Properties[$_].Value}} |
ft -auto
给出(经过一点审查,并注意到在索引#8处获取登录类型的更好方法):
Idx 属性 --- -------- 0 秒-1-5-18 1 *计算机账户* 2 *计算机领域* 3 999 4 *用户的 SID* 5 *用户的用户名* 6 *用户域* 7 151556 8 10 9 用户 32 10 协商 11 *计算机名称* 12 00000000-0000-0000-0000-0000-00000000000 13 - 14 - 15 0 16 2964 17 C:\Windows\System32\winlogon.exe 18 *客户端 IP* 19 15532
答案2
我会这样做 -
$filter = "<QueryList>" + `
"<Query Id=`"0`" Path=`"Security`">" + `
"<Select Path=`"Security`">" + `
"*[System[(EventID=4624) and " + `
"TimeCreated[@SystemTime>='2011-09-21T06:00:00Z' and @SystemTime<'2011-09-22T06:00:00Z']]] and " + `
"*[EventData[Data[@Name=`'LogonType`']=10]]" + `
"</Select>" + `
"<Suppress Path=`"Security`">" + `
"*[EventData[Data[@Name=`'LogonGuid`']=`'{00000000-0000-0000-0000-000000000000}`']]" + `
"</Suppress>" + `
"</Query>" + `
"</QueryList>"
Get-WinEvent -FilterXML $filter |
%{ [xml]$xml = $_.ToXml()
$xml.getElementsByTagName("Data") | where{$_.name -eq "TargetUserName"} |
select '#text'
}
编辑:现在返回个人姓名。您可以尝试从该 XML 文档中提取具体内容。
注意:您需要对 TimeCreated 值进行一些调整(可能在运行中生成它们)。我将它们包括在内,以便您可以看到它们所需的格式。
Get-WinEvent 将很多比 Get-EventLog 更快,因为过滤将在服务器端完成,而不是在管道中完成。您还可以使用 FilterXML 参数对查询进行更具体的设置。与登录事件相关的用户名位于Message
返回的属性中EventLogRecord
。