Показать полную графическую версию : Как отфильтровать вывод скрипта, удалив из него строки с подстрокой
Всем доброе время.
Нашел в сети powershell скрипт и допилил его под себя. (для русской Windows Server)
Он на windows Server (2016) читает лог успешных попыток входа и выводит их за определенное время.
Выводит он что-то типа такого:
TimeGenerated ClientIP Username LogType
------------- -------- -------- -------
23.04.2020 10:45:33 - -\СИСТЕМА Service
23.04.2020 10:41:44 - -\СИСТЕМА Service
23.04.2020 10:41:44 - -\СИСТЕМА Service
23.04.2020 10:35:26 192.168.0.66 MAINS\acidс RDP
23.04.2020 10:35:26 192.168.0.66 MAINS\acidс RDP
23.04.2020 10:35:25 - -\DWM-16 Interactive - local logon
Можно ли как-то куда-то перенаправить вывод, чтобы отфильтровать строки, содержащие "-\СИСТЕМА"?
Чтобы остались только:
23.04.2020 10:35:26 192.168.0.66 MAINS\acidс RDP
23.04.2020 10:35:25 - -\DWM-16 Interactive - local logon
Get-EventLog -LogName Security -after ((Get-date).AddMinutes(-200))| ?{(4624) -contains $_.EventID -and $_.Message -match ‘Тип входа:’}| %{
#rdp - 10, без него будет выводить все логины match 'Тип входа:\s+(10)\s'
(new-object -Type PSObject -Property @{
TimeGenerated = $_.TimeGenerated
ClientIP = $_.Message -replace '(?smi).*Сетевой адрес источника:\s+([^\s]+)\s+.*','$1'
UserName =(([regex]'(?<=Новый вход:.*[\s\S]*.*записи:.\s)([\s\S]*)(?=\s\n.*Домен)').match($_.message).value)
UserDomain = $_.Message -replace '(?smi).*Имя рабочей станции:\s+([^\s]+)\s+.*','$1'
LogonType = $_.Message -replace '(?smi).*Тип входа:\s+([^\s]+)\s+.*','$1'
})
} | sort TimeGenerated -Descending | Select TimeGenerated, ClientIP `
, @{N='Username';E={'{0}\{1}' -f $_.UserDomain,$_.UserName}} `
, @{N='LogType';E={
switch ($_.LogonType) {
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'}
default {"LogType Not Recognised: $($_.LogonType)"}
}
}}
перед sort where {$_.UserDomain -ne '-' -and $_.UserName.tolower() -ne 'система'} |
Эта комманда удаляет все, где есть -.
Удаляет и такие строки: 23.04.2020 11:48:34 202.137.7.58 -\АНОНИМНЫЙ ВХОД Network conection to shared folder
23.04.2020 10:35:25 - -\DWM-16 Interactive - local logon
Ура! Я понял принцип...
Вот так работает! where UserName -ne 'СИСТЕМА'
Thanks!
Подскажите еще pls, можно как-то в выводе этом не выводить первые строчки?
Выводить данные, но не выводить их описание?
TimeGenerated ClientIP Username LogType
------------- -------- -------- -------
Наковырял такой способ:
ConvertTo-Csv -NoType | Select-Object -Skip 1
Получаем что-то типа:
"23.04.2020 16:56:54","202.166.174.27","-\АНОНИМНЫЙ ВХОД","Network conection to shared folder"
"23.04.2020 16:56:54","202.166.174.27","-\АНОНИМНЫЙ ВХОД","Network conection to shared folder"
Только кавычки теперь глаза мозолят, можно как-то кавычки все убрать? :)
Format-Table -HideTableHeaders можно
Ура! Получилось то, что нужно может кому пригодится.
На Windows Server запускается этот скрипт каждый час и пишет в лог за последний час успешные входы в систему, с какого IP кто именно, какой тип соединения. Соотвественно имеем лог входов в систему.
Get-EventLog -LogName Security -after ((Get-date).AddMinutes(-60))| ?{(4624) -contains $_.EventID -and $_.Message -match ‘Тип входа:’}| %{
#rdp - 10, без него будет выводить все логины match 'Тип входа:\s+(10)\s'
(new-object -Type PSObject -Property @{
TimeGenerated = $_.TimeGenerated
ClientIP = $_.Message -replace '(?smi).*Сетевой адрес источника:\s+([^\s]+)\s+.*','$1'
UserName =(([regex]'(?<=Новый вход:.*[\s\S]*.*записи:.\s)([\s\S]*)(?=\s\n.*Домен)').match($_.message).value)
UserDomain = $_.Message -replace '(?smi).*Имя рабочей станции:\s+([^\s]+)\s+.*','$1'
LogonType = $_.Message -replace '(?smi).*Тип входа:\s+([^\s]+)\s+.*','$1'
})
} | where ClientIP -ne '-' | sort TimeGenerated -Descending | Select TimeGenerated, ClientIP `
, @{N='Username';E={'{0}\{1}' -f $_.UserDomain,$_.UserName}} `
, @{N='LogType';E={
switch ($_.LogonType) {
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'}
default {"LogType Not Recognised: $($_.LogonType)"}
}
}} | ConvertTo-Csv -NoType | Select-Object -Skip 1 | % {$_ -replace '"',''} >> C:\logs\logons\logon.txt
Format-Table -HideTableHeaders можно »
Блин, спасибо, так тоже выглядит зачетно. :)
запускается этот скрипт каждый час и пишет в лог за последний час успешные входы в систему, с какого IP кто именно, какой тип соединения. Соотвественно имеем лог входов в систему. »
Вот только пропускать будете или дублировать записи. Надо не (Get-date).AddMinutes(-60), а хотя бы надо хранить время последнего запроса и использовать его.
Вот только пропускать будете или дублировать записи. Надо не (Get-date).AddMinutes(-60), а хотя бы надо хранить время последнего запроса и использовать его. »
Потеряться точно ничего не потеряется, запускается скрипт ровно в 8:00:00, это значит, что он возьмет информацию с 7:00:00 до того, что появится в базе, если он выполняется скажем 15 секунд, то продублироваться могут пару записей за эти 15 секунд, пара избыточных записей мне погоды не сделает, а вот теряться они тут не будут, так как информация берется четко за 1 час.
Посмотрел логи - ни одной дублирующей записи пока не нашел, понаблюдаю дальше.
В принципе правильнее было бы может быть отслеживать время записи последнего события в логе и стартовать от него, нужно хранить это время в файлике и перед стартом скрипта указывать это время как стартовое. Или читать последнюю строчку лог файла и брать из нее время.
Есть ли такая функция как в unix подобных системах? Чтобы не затрачивать время на чтение всего файла, скажем который вырастет до 50Мб, и добавит время работы скрипта?
Вот такой строчкой скажем сейчас заканчивается файл.
24.04.2020 4:15:10,201.216.208.137,-\АНОНИМНЫЙ ВХОД,Network conection to shared folder
Кстати сделано это все для отслеживания левых подключений, пытаюсь понять, что это за левые Анонимные входы с левых IP.
Хотя придумал простой способ, нужно брать время последнего изменения файла и стартовать от него.
Скрипт запустился в 5:00
Закончил работу в 24 апреля 2020 г., 5:00:23 по времени изменения файла.
Берем это время и старт от него, будет точнее.
Что-то типа такого(файл должен существовать, если это первый запуск, можно создать пустой, лом добавлять это):
$file = Get-Item 'C:\logs\logons\logon.txt'
Get-EventLog -LogName Security -after $file.LastWriteTime | ?{(4624) -contains $_.EventID -and $_.Message -match ‘Тип входа:’}| %{
#rdp - 10, без него будет выводить все логины match 'Тип входа:\s+(10)\s'
(new-object -Type PSObject -Property @{
TimeGenerated = $_.TimeGenerated
ClientIP = $_.Message -replace '(?smi).*Сетевой адрес источника:\s+([^\s]+)\s+.*','$1'
UserName =(([regex]'(?<=Новый вход:.*[\s\S]*.*записи:.\s)([\s\S]*)(?=\s\n.*Домен)').match($_.message).value)
UserDomain = $_.Message -replace '(?smi).*Имя рабочей станции:\s+([^\s]+)\s+.*','$1'
LogonType = $_.Message -replace '(?smi).*Тип входа:\s+([^\s]+)\s+.*','$1'
})
} | where ClientIP -ne '-' | sort TimeGenerated -Descending | Select TimeGenerated, ClientIP `
, @{N='Username';E={'{0}\{1}' -f $_.UserDomain,$_.UserName}} `
, @{N='LogType';E={
switch ($_.LogonType) {
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'}
default {"LogType Not Recognised: $($_.LogonType)"}
}
}} | ConvertTo-Csv -NoType | Select-Object -Skip 1 | % {$_ -replace '"',''} >> C:\logs\logons\logon.txt
#}} | Format-Table -HideTableHeaders >> C:\logs\logons\logon.txt
rises, по поводу «Такого не может быть, потому что такого не может быть никогда» — оставлю на Вашей совести. Это… такое себе… Как показывает практика, то, что может произойти — рано или поздно, но происходит.
нужно хранить это время в файлике »
Или в реестре. Но лучше вообще поменять парадигму (см. ниже).
Или читать последнюю строчку лог файла и брать из нее время.
Есть ли такая функция как в unix подобных системах? Чтобы не затрачивать время на чтение всего файла, скажем который вырастет до 50Мб, и добавит время работы скрипта? »
Писать лучше всего не в текстовый файл, а в базу данных, пусть даже в mdb. Поскольку содержимым базы данных легко манипулировать — и запросы произвольные к ней составлять, и время последней записи получать и прочая, и прочая…
Я согласен, что можно сделать красиво, но лично для моих целей этого достаточно. Благодаря этому логу я наглядно вижу, что попытки анонимного доступа прекращены и бонусом к этому я имею себе лог файл времени и источника входа пользователей на сервер. Можно допилить и сделать качественный и правильный продукт, но тут уже вопрос цель/средство. Может быть кто-то допилит этот скрипт и сделает что-то более красивое и правильное. ;-)
все данные можно взять из массива строк ReplacementStrings (https://docs.microsoft.com/en-us/dotnet/api/system.diagnostics.eventlogentry.replacementstrings?view=netframework-4.8#System_Diagnostics_EventLogEntry_ReplacementStrings), и желательно не лезть в Message c тяжёлыми регулярками.
структура ReplacementStrings привязана к eventid, поэтому идея такая
$eventid = 4624
$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 (get-date).AddMinutes(-1000) |
select TimeGenerated, ReplacementStrings |
where {$arr = $_.ReplacementStrings; $arr[18] -ne '-'} | #IP
foreach {
$ip = $arr[18]
$domain_name = $arr[5] + @('', ('\' + $arr[11]))[[bool]$arr[11]]
$logontype = $arr[8] + ':' + $logontypes[[int]$arr[8]]
$_.TimeGenerated, $ip, $domain_name, $logontype -join '; '
}
Sham, крутецкая тема, спасибо, может кому еще сгодится. :-)
Вот такой код оставил, крутится нормально. Запускается шедулером через каждые пол часа.
Берет время изменения файла и от него выводит лог.
$file = Get-Item 'C:\logs\logons\logon.txt'
$eventid = 4624
$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 |
where {$arr = $_.ReplacementStrings; $arr[18] -ne '-'} | #IP
foreach {
$ip = $arr[18]
$domain_name = $arr[5] + @('', ('\' + $arr[11]))[[bool]$arr[11]]
$logontype = $arr[8] + ':' + $logontypes[[int]$arr[8]]
$_.TimeGenerated, $ip, $domain_name, $logontype -join '; '
} >> C:\logs\logons\logon.txt
Кстати заметил, что скрипт немного несвязно выводит даты, можно как-то вывод упорядочить по дате и времени?
Выводит как-то так:
07.05.2020 14:36:44; 192.168.0.249; АНОНИМНЫЙ ВХОД\JUL; 3:Network conection to shared folder)
07.05.2020 15:30:01; 192.168.0.249; АНОНИМНЫЙ ВХОД\JUL; 3:Network conection to shared folder)
07.05.2020 15:25:21; 192.168.0.249; АНОНИМНЫЙ ВХОД\JUL; 3:Network conection to shared folder)
Foreigner
08-05-2020, 00:03
можно как-то вывод упорядочить по дате и времени? »
....|
select TimeGenerated, ReplacementStrings | sort TimeGenerated |
where....
Foreigner, спасибо, вроде бы едет.
overrise
16-05-2020, 19:56
А можно как-то добавить сюда не только логин, но и дисконнект?
Если добавить событие $eventid = 4624,4779, то он пишет в лог IP адрес, но не пишет имени пользователя, можно это как-то подправить?
Тогда лог будет более полноценным и на коннект и на дисконнект?
Пишет на дисконнект так:
16.05.2020 19:30:00; 192.168.20.74; serg\FILESERVER; 10:RDP
16.05.2020 19:40:16; ; 192.168.20.74; :
16.05.2020 19:40:21; 192.168.20.74; serg\LAPTOP; 3:Network conection to shared folder
© OSzone.net 2001-2012
vBulletin v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.