Имя пользователя:
Пароль:  
Помощь | Регистрация | Забыли пароль?  | Правила  

Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Скриптовые языки администрирования Windows » PowerShell - Как отфильтровать вывод скрипта, удалив из него строки с подстрокой

Ответить
Настройки темы
PowerShell - Как отфильтровать вывод скрипта, удалив из него строки с подстрокой

Новый участник


Сообщения: 14
Благодарности: 0

Профиль | Отправить PM | Цитировать


Всем доброе время.

Нашел в сети 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)"}
}
}}

Отправлено: 11:13, 23-04-2020

 

Новый участник


Сообщения: 18
Благодарности: 0

Профиль | Отправить PM | Цитировать


Я победил эту тему немного тупо, но зато результат правильный, скрипт супер

Выводит так:

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 '; '
	}
Цитата Foreigner:
Забыл точку после $_ »
Выводит такое, но походу проще просто в массиве взять то, что нужно и поменять местами, если событие - 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

Последний раз редактировалось overrise, 18-05-2020 в 09:47.


Отправлено: 09:28, 18-05-2020 | #31



Для отключения данного рекламного блока вам необходимо зарегистрироваться или войти с учетной записью социальной сети.

Если же вы забыли свой пароль на форуме, то воспользуйтесь данной ссылкой для восстановления пароля.


Аватара для YuS_2

Crazy


Contributor


Сообщения: 1171
Благодарности: 487

Профиль | Отправить PM | Цитировать


Цитата overrise:
Вот XML события »
Давненько уже, делал скрипт немного для других целей, хоть командлет используется другой get-winevent, но "умеет" парсить элементы EventData... плюс, учитывая микрософтовское:
Цитата:
Get-EventLog использует Win32 API, который устарел. Результаты могут быть неточными. Используйте Get-WinEvent вместо этого командлета.
вот, собственно:
script.ps1
Код: Выделить весь код
#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
}

- может пригодится...

-------
scio me nihil scire. Ѫ


Последний раз редактировалось YuS_2, 18-05-2020 в 10:31.


Отправлено: 10:19, 18-05-2020 | #32



Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Скриптовые языки администрирования Windows » PowerShell - Как отфильтровать вывод скрипта, удалив из него строки с подстрокой

Участник сейчас на форуме Участник сейчас на форуме Участник вне форума Участник вне форума Автор темы Автор темы Шапка темы Сообщение прикреплено

Похожие темы
Название темы Автор Информация о форуме Ответов Последнее сообщение
PowerShell - [решено] Как вставить в тело сообщения вывод из данного скрипта - LLC Скриптовые языки администрирования Windows 8 06-04-2015 08:36
CMD/BAT - [решено] Вычитание символов из строки и вывод на экран Instant_SR Скриптовые языки администрирования Windows 4 25-07-2013 11:37
CMD/BAT - [решено] Копирование имени файла и определённой строки из него в другой файл Liquid Ocelot Скриптовые языки администрирования Windows 10 05-07-2013 09:35
CMD/BAT - [решено] вывод строки из *.xml LAKERS824 Скриптовые языки администрирования Windows 26 08-07-2012 00:09
Запуск PHP-скрипта из командной строки Windows vadimiron Вебмастеру 4 01-12-2005 15:12




 
Переход