Войти

Показать полную графическую версию : Как отфильтровать вывод скрипта, удалив из него строки с подстрокой


Страниц : 1 [2]

Foreigner
16-05-2020, 21:36
overrise,
но не пишет имени пользователя

Значит в самом логе UserName пустой.

overrise
17-05-2020, 09:47
В самом событии дисконнекта, если на него посмотреть, есть и имя и пк с которого вышел пользователь и его IP.
Если в журнале Windows отфильтровать событие 4779(Данное событие возникает, когда пользователь отключается от существующего сеанса служб терминалов либо переключается с существующего рабочего стола с помощью быстрого переключения пользователей.), я вижу:

AccountName serg
AccountDomain FILESERVER
LogonID 0xe44811e
SessionName RDP-Tcp#58
ClientName LAPTOP
ClientAddress 192.168.20.74

Может быть дело в парсинге данных?

Foreigner
17-05-2020, 11:31
Может быть дело в парсинге данных? »

Может быть. Выложите, как выглядят эти два события. У меня нет ни одного 4779.

overrise
17-05-2020, 18:35
Странно, при дисконнекте по RDP выскакивать должно это событие по любому. Законнектиться, закрыть соединение и оно появляется.

Вот XML события:

- <Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
- <System>
<Provider Name="Microsoft-Windows-Security-Auditing" Guid="{54849625-5478-4994-A5BA-3E3B0328C30D}" />
<EventID>4779</EventID>
<Version>0</Version>
<Level>0</Level>
<Task>12551</Task>
<Opcode>0</Opcode>
<Keywords>0x8020000000000000</Keywords>
<TimeCreated SystemTime="2020-05-16T16:29:54.469735400Z" />
<EventRecordID>167278009</EventRecordID>
<Correlation ActivityID="{C2DFD717-2AEC-0000-1DD7-DFC2EC2AD601}" />
<Execution ProcessID="736" ThreadID="3856" />
<Channel>Security</Channel>
<Computer>fileserver</Computer>
<Security />
</System>
- <EventData>
<Data Name="AccountName">serg</Data>
<Data Name="AccountDomain">FILESERVER</Data>
<Data Name="LogonID">0xe44811e</Data>
<Data Name="SessionName">RDP-Tcp#58</Data>
<Data Name="ClientName">LAPTOP</Data>
<Data Name="ClientAddress">192.168.20.74</Data>
</EventData>
</Event>

Foreigner
17-05-2020, 23:16
Ну а так, что-нибудь показывает?


$report =
Get-EventLog -LogName Security -InstanceID 4624,4779 -Newest 10 |
Foreach-Object {

[PSCustomObject] @{

InstanceID = $_.InstanceID
EventID = $_.EventID
MachineName = $_.MachineName
UserName = $_.ReplacementStrings[5]
TimeGenerated = $_.TimeGenerated
}
}

$report | Sort-Object TimeGenerated | Format-Table

overrise
18-05-2020, 08:20
Вот такое выдает, по ходу там имя пользователя в другой переменной хранится при дисконнекте, если я правильно понимаю:

InstanceID EventID MachineName UserName TimeGenerated
---------- ------- ----------- -------- -------------
4624 4624 fileserver serg 18.05.2020 8:15:03
4624 4624 fileserver serg 18.05.2020 8:15:03
4624 4624 fileserver DWM-7 18.05.2020 8:15:03
4624 4624 fileserver DWM-7 18.05.2020 8:15:03
4779 4779 fileserver 192.168.20.74 18.05.2020 8:15:51
4624 4624 fileserver serg 18.05.2020 8:16:02
4624 4624 fileserver serg 18.05.2020 8:16:03
4624 4624 fileserver serg 18.05.2020 8:16:03
4624 4624 fileserver DWM-7 18.05.2020 8:16:03
4624 4624 fileserver DWM-7 18.05.2020 8:16:03

overrise
18-05-2020, 08:41
Если я беру событие 4779 и вывожу echo $_.ReplacementStrings, то получаю вот такие ответы:

serg
FILESERVER
0xe44811e
RDP-Tcp#77
LAPTOP
192.168.20.74

serg
FILESERVER
0xe44811e
RDP-Tcp#78
LAPTOP
192.168.20.74

Foreigner
18-05-2020, 08:53
то получаю вот такие ответы »
Это для одного события 4779 или для двух? Вообще как-то странно, имхо, должен быть какой-то стандарт. Не прописывать же условия для каждого события:

$report =
Get-EventLog -LogName Security -InstanceID 4624,4779 -Newest 10 |
Foreach-Object {

if ($_InstanceID -eq 4624) { $n = 5 }
else { $n = 0 }

[PSCustomObject] @{

InstanceID = $_.InstanceID
EventID = $_.EventID
MachineName = $_.MachineName
UserName = $_.ReplacementStrings[$n]
TimeGenerated = $_.TimeGenerated
}
}

$report | Sort-Object TimeGenerated | Format-Table

overrise
18-05-2020, 08:55
При этом 4624:

S-1-0-0
-
-
0x0
S-1-5-21-2348659260-1389582479-2633529765-1000
serg
FILESERVER
0x1eba2ed5
3
NtLmSsp
NTLM
LAPTOP
{00000000-0000-0000-0000-000000000000}
-
NTLM V2
128
0x0
-
192.168.20.74
0
%%1833
-
-
-
%%1843
0x0
%%1843

Это для одного события 4779 или для двух? Вообще как-то странно, имхо, должен быть какой-то стандарт. Не прописывать же условия для каждого события: »

Это два события.

А вот что выдает новый скрипт:

InstanceID EventID MachineName UserName TimeGenerated
---------- ------- ----------- -------- -------------
4624 4624 fileserver S-1-5-18 18.05.2020 8:45:01
4624 4624 fileserver S-1-5-18 18.05.2020 8:45:01
4624 4624 fileserver S-1-5-18 18.05.2020 8:50:00
4624 4624 fileserver S-1-5-18 18.05.2020 8:55:00
4779 4779 fileserver serg 18.05.2020 8:56:27
4624 4624 fileserver S-1-0-0 18.05.2020 8:56:33
4624 4624 fileserver S-1-5-18 18.05.2020 8:56:34
4624 4624 fileserver S-1-5-18 18.05.2020 8:56:34
4624 4624 fileserver S-1-5-18 18.05.2020 8:56:34
4624 4624 fileserver S-1-5-18 18.05.2020 8:56:34

Походу да, Microsoft решила сделать для каждого события свой набор переменных.

Foreigner
18-05-2020, 09:02
Забыл точку после $_

if ($_.InstanceID

overrise
18-05-2020, 09:28
Я победил эту тему немного тупо, но зато результат правильный, скрипт супер :)

Выводит так:

18.05.2020 8:56:27; 46.219.124.185; serg\LAPTOP; DISCONNECT
18.05.2020 8:56:33; 46.219.124.185; serg\LAPTOP; 3:Network conection to shared folder)
18.05.2020 8:56:34; 46.219.124.185; serg\FILESERVER; 10:RDP

$eventid = 4624,4779
$logontypes = @{
2 = 'Interactive - local logon';
3 = 'Network conection to shared folder)';
4 = 'Batch';
5 = 'Service';
7 = 'Unlock (after screensaver)';
8 = 'NetworkCleartext';
9 = 'NewCredentials (local impersonation process under existing connection)';
10 = 'RDP';
11 = 'CachedInteractive'
}

get-eventlog -LogName Security -InstanceId $eventid -after ($file.LastWriteTime) |
select TimeGenerated, ReplacementStrings | sort TimeGenerated |
where {
$arr = $_.ReplacementStrings; $arr[18] -ne '-'} | #IP
foreach {
$ip = $arr[18]
$usernam = $arr[0]+'\'+$arr[4]

$domain_name = $arr[5] + @('', ('\' + $arr[11]))[[bool]$arr[11]]
$logontype = $arr[8] + ':' + $logontypes[[int]$arr[8]]

if ($arr[0].Contains("S-")) {$usernam=''} else {$ip=$arr[5]
$domain_name=$usernam
$logontype='DISCONNECT'}

$_.TimeGenerated, $ip, $domain_name, $logontype -join '; '
}

Забыл точку после $_ »

Выводит такое, но походу проще просто в массиве взять то, что нужно и поменять местами, если событие - disconnect, так как выдача разная, то и результат приходится парсить.

InstanceID EventID MachineName UserName TimeGenerated
---------- ------- ----------- -------- -------------
4624 4624 fileserver serg 18.05.2020 9:30:00
4624 4624 fileserver serg 18.05.2020 9:30:01
4624 4624 fileserver serg 18.05.2020 9:30:01
4624 4624 fileserver serg 18.05.2020 9:30:01
4779 4779 fileserver serg 18.05.2020 9:33:14
4624 4624 fileserver serg 18.05.2020 9:33:18
4624 4624 fileserver serg 18.05.2020 9:33:19
4624 4624 fileserver serg 18.05.2020 9:33:19
4624 4624 fileserver DWM-7 18.05.2020 9:33:19
4624 4624 fileserver DWM-7 18.05.2020 9:33:19

YuS_2
18-05-2020, 10:19
Вот XML события »
Давненько уже, делал скрипт немного для других целей, хоть командлет используется другой get-winevent, но "умеет" парсить элементы EventData... плюс, учитывая микрософтовское:
Get-EventLog использует Win32 API, который устарел. Результаты могут быть неточными. Используйте Get-WinEvent вместо этого командлета.
вот, собственно:
#requires -v 5.0
#requires -runas
<#
Version 2.0.1.000
Date 27.02.2019
Добавлены все параметры командлета get-winevent
Переработаны фильтры
Добавлен ключ -data, без него не будет вывода дополнительной информации из узлов DATA из отобранных событий, т.е. скрипт работает в режиме автоматизации сборки фильтра событий и только.
---
Version 2.0.1.005
Date 27.02.2019
изменение типа данных ввода учетной записи
Поправлены старые баги...
Добавлены новые... :)


Все значения, заданные в параметрах, приведены для примера, их лучше удалить и задавать в параметрах скрипта
Примеры использования:
.\script.ps1 -logname 'Microsoft-Windows-Diagnostics-Performance/Operational' -arg '^(boottime|start|bootstart|bootend)' -max 50 -eventid 100,103 -data
.\script.ps1 -logname 'Microsoft-Windows-Diagnostics-Performance/Operational' -arg '^(boottime|start|bootstart|bootend)' -max 50 -eventid 100 -data|ft
.\script.ps1 -logname 'Microsoft-Windows-Diagnostics-Performance/Operational' -arg '.' -max 50 -eventid 100,103 -data|out-gridview
.\script.ps1 -listl '*'|out-gridview
.\script.ps1 -listl '*intel*'

Level
0 - всегда записывать;
1 - Критический;
2 - Ошибка;
3 - Предупреждение;
4 - Сведения;
5 - Подробности (Verbose).
#>

[cmdletbinding()]
param (
[string]$computername, # Имя компьютера с которого получаем данные журналов
$credential, # Ввод учетных данных
[string[]]$logname, #= "Microsoft-Windows-Diagnostics-Performance/Operational", # Наименование лога (пути с именем журнала)
[string[]]$listlog, # Получение списка указанных журналов событий, все журналы - *
[string[]]$listprovider, # Получение списка указанных поставщиков
[int64]$maxevents, #= 30, # Число событий для отчета
[switch]$force, # Дополнительное получение аналитических и отладочных журналов, если используются символы подстановки
[switch]$oldest, # Формирование списка от наиболее старого к новому
[string[]]$path, # Путь к указанным файлам логов, поддерживаются .evt, .evtx, .etl расширения
[string[]]$providername, # Получение событий, записанных указанными поставщиками (поддерживаются подстановочные знаки)
[string]$arguments = '.', #'^(boottime|start|bootstart|bootend)', # Шаблон для отбора элементов из узлов EventData
[int[]]$level, #= (4), # Уровни для отбора событий
[int[]]$eventid, #= (100,103,108) # ID событий для отбора
[switch]$data #= $true # Переключатель для получения дополнительных данных из узлов Data в отобранных событиях
)

# Формируем простой фильтр XPath, если указаны $level или $eventid
function map_prefix ($prefix, $var){
if ($var){
'('+ (($var|%{"{0}{1}" -f $prefix,"$_"}) -join ' or ') + ')'
}
}

$levels = map_prefix 'Level=' $level
$eventids = map_prefix 'EventID=' $eventid

$arr = $eventids,$levels
if ($arr -ne $null) {$flt = "*[System[$(($arr -ne $null) -join ' and ')]]"}

# Формируем строку параметров командлета
$pars = @{}
if($computername){$pars.computername="$computername"}
if($logname){$pars.logname="$logname"}
if($computername -and $credential){$pars.credential = Get-Credential -cred $credential}
if($listlog){$pars.listlog=$listlog}
if($listprovider){$pars.listprovider=$listprovider}
if($maxevents){$pars.maxevents=$maxevents}
if($oldest){$pars.oldest=$true}
if($force){$pars.force=$true}
if($path){$pars.path=$path}
if($providername){$pars.providername=$providername}
if($flt){$pars.filterxpath="$flt"}


if ($data){
# Получаем результат работы командлета
$events = get-winevent @pars
# Фильтр элементов в событиях по шаблону
$elname = ([xml[]]$events.toxml()).event.eventdata.data.name
$sel = if (($a = $elname -match $arguments) -eq $true){$elname} else {$a|sort -uni}

$z=-1
# Добавляем свойства к объектам
foreach ($event in $events){
$xml = [xml]$event.toxml()
if ($xml.event.eventdata.data.count){
for ($i=0;$i -lt $xml.event.eventdata.data.count;$i++){
if($xml.event.eventdata.data[$i].name){
$name = $xml.event.eventdata.data[$i].name
$val = $xml.event.eventdata.data[$i].'#text'
} else {
$name = 'Data' + "$i"
if ($i -gt $z) {[array]$darr += $name;$z = $i}
$val = $xml.event.eventdata.data[$i]
}
$val = if([datetime]::tryparse($val,[ref](get-date))){get-date $val} else {$val}
add-member -inp $event -mem noteproperty -force -name $name -val $val
}
}
}

# Формируем строку отбираемых свойств
$head = 'timecreated','id','level','leveldisplayname'
if($darr){
# Фильтруем созданные свойства DataN, у которых не было аргументов
$fdarr = if(($b = $darr -match $arguments) -eq $true){$darr} else {$b}
if ($sel){
$sel = $head + $fdarr + $sel + '*'
} else {$sel = $head + $fdarr + '*' }
} elseif ($sel) {
$sel = $head + $sel + '*'
} else {$sel = $head + '*'}

# Выводим результат
$obj = try {$events|select $sel -ea 0} catch {continue}
$obj|select *
} else {
get-winevent @pars
}
- может пригодится...




© OSzone.net 2001-2012