Crazy
Сообщения: 1171
Благодарности: 487
|
Профиль
|
Отправить PM
| Цитировать
Цитата rango13:
Изучаю PS-скрипты, интересны советы по их оптимизации. »
|
Если говорить об изучении, то... есть такой скрипт, который из логов выковыривает дополнительные элементы:
сырой, но рабочий набросок
Код:
# Идея: https://blogs.technet.microsoft.com/ashleymcglone/2013/08/28/powershell-get-winevent-xml-madness-getting-details-from-event-logs/
#requires -v 5.0
#requires -runas
<#
Version 2.0.1.000
Date 27.02.19
Добавлены все параметры командлета get-winevent
Переработаны фильтры
Добавлен ключ -data, без него не будет вывода дополнительной информации из узлов DATA из отобранных событий, т.е. скрипт работает в режиме автоматизации сборки фильтра событий и только.
---
Version 2.0.1.005
Date 27.02.2019
изменение типа данных ввода учетной записи
Поправлены старые баги...
Добавлены новые... :)
Все значения, заданные в параметрах, приведены для примера, их лучше удалить и задавать в параметрах скрипта
Примеры использования:
.\script.ps1 'Microsoft-Windows-Diagnostics-Performance/Operational' '^(boottime|start|bootstart|bootend)' -max 50 -eventid 100,103 -data
.\script.ps1 'Microsoft-Windows-Diagnostics-Performance/Operational' '^(boottime|start|bootstart|bootend)' -max 50 -eventid 100 -data|ft
.\script.ps1 'Microsoft-Windows-Diagnostics-Performance/Operational' '.' -max 50 -eventid 100,103 -data|out-gridview
.\script.ps1|out-gridview
.\script.ps1
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
}
|