2016-08-18 2 views
1

Я спотыкаюсь с powershell.Powershell: извлечение данных из файла журнала для создания нового объекта

У меня есть скрипт, который разбирает тот же файл журнала на сотни добывающие двух типов ПК сделок мы заинтересованы.

эта строка делает сопоставление с образцом экономии каждой строки журнала в одной переменной, которая содержит несколько строк. Я конвертирую объект соответствия в строку, чтобы впоследствии его разделить.

$strLogEvents = select-string -path \\$Cmpname\c$\ProgramData\IS\Logs\DMS\outlook.* -pattern '(doFolderDocSearch ends, duration)|(doDocSearch ends, duration)' | ForEach-Object {$_.ToString()} 

вот что держит $ StrLogEvents для одного ПК

\\naimc\c$\ProgramData\IS\Logs\DMS\OUTLOOK.log:325:Wed 08/17 10:24:44.983 PerformanceContext: 59:Info2 [10728] System call doDocSearch ends, duration 60203 ms 
\\naimc\c$\ProgramData\IS\Logs\DMS\OUTLOOK.log_bak:886:Fri 08/05 16:23:14.249 PerformanceContext: 59:Info2 [12204] System call DoFolderDocSearch ends, duration 1796 ms 
\\naimc\c$\ProgramData\IS\Logs\DMS\OUTLOOK.log_bak:963:Fri 08/05 16:23:27.901 PerformanceContext: 59:Info2 [12204] System call DoFolderDocSearch ends, duration 250 ms 
\\naimc\c$\ProgramData\IS\Logs\DMS\OUTLOOK.log_bak:1046:Fri 08/05 16:23:41.625 PerformanceContext: 59:Info2 [12204] System call doDocSearch ends, duration 171 ms 
\\naimc\c$\ProgramData\IS\Logs\DMS\OUTLOOK.log_bak:1422:Sun 08/07 23:08:49.107 PerformanceContext: 59:Info2 [12204] System call DoFolderDocSearch ends, duration 250 ms 
\\naimc\c$\ProgramData\IS\Logs\DMS\OUTLOOK.log_bak:1786:Sun 08/07 23:09:42.750 PerformanceContext: 59:Info2 [12204] System call doDocSearch ends, duration 407 ms 
\\naimc\c$\ProgramData\IS\Logs\DMS\OUTLOOK.log_bak:1847:Sun 08/07 23:10:05.494 PerformanceContext: 59:Info2 [12204] System call doDocSearch ends, duration 454 ms 

Для каждой линии Меня интересует только в переподготовке имякомпьютера, дата, время, тип системного вызова, длительность в миллисекундах.

я могу дальше ломок массив строк с этим:

$ParsedLogEvents = $strLogEvents | ForEach-Object {$_.split("\, ",[System.StringSplitOptions]::RemoveEmptyEntries)} 

Строка в $ ParsedLogEvents теперь содержит одну чистую строку для каждого «куска» данные

Примера: Каждый элемент на это собственная линия. Я добавил *** для обозначения строк, которые хочу сохранить.

naimc***-PCName 
c$ 
ProgramData 
IS 
Logs 
DMS 
OUTLOOK.log_bak:4602:Mon 
08/15*** -Date 
14:36:01.667 -Time 
PerformanceContext: 
59:Info2 
[10928] 
System 
call 
doDocSearch ***-EventType 
ends 
duration 
47 ***-Duration 
ms 
naimc 
c$ 
ProgramData 
Osler 
IS 
Logs 
DMS 
OUTLOOK.log_bak:4610:Mon 
08/15 
14:36:01.748 
PerformanceContext: 
59:Info2 
[10928] 
System 
call 
doDocSearch 
ends 
duration 
31 
ms 

Я думаю, что мне приходится обрабатывать каждую строку как одну переменную. (не могу понять, как сделать эту простую часть). После того, как я смог просто использовать $ ParsedLogEvents [lineNumber], чтобы вернуть записи для строк, которые я хочу сохранить, чтобы создать хеш-таблицу или объект. это позволит мне сохранить CSV или экспортировать в базу данных SQL. Я не могу этого сделать, потому что каждая строка всех исходных событий находится внутри этого большого массива.

Любые предложения? Я направляюсь в правильном направлении.

ответ

3

ли поле разбора в Select-String с помощью названных групп регулярного выражения:

$report = select-string ` 
    -path \\$Cmpname\c$\ProgramData\IS\Logs\DMS\outlook.* ` 
    -pattern ('(?<date>.+? .+?) ' + 
     '(?<time>.+?) .+? ' + 
     '(?<syscall>doFolderDocSearch|doDocSearch) ends, duration ' + 
     '(?<duration>.+?) ms') ` 
| %{ 
    $g = $_.matches[0].groups 
    @{ 
     computer = $Cmpname 
     date = $g['date'].value 
     time = $g['time'].value 
     syscall = $g['syscall'].value 
     duration = $g['duration'].value 
    } 
} 

произведет массив объектов доступного в качестве $report[1].computer, $report[1].date, и так далее:

Name       Value 
----       ----- 
date       Wed 08/17 
time       10:24:44.983 
syscall      doDocSearch 
computer      naimc 
duration      60203 
+0

Очень хороший, но слишком хардкор для моего понимания. По какой-то причине ваше исходное предложение не вернуло никаких результатов, но я сделал добавление – user3019228

+0

Возможно, вы используете powershell2 или 3?Код работает как на PS4. – wOxxOm

0

Очень приятно! Это первый пример, который я вижу в названных группах регулярных выражений.

По какой-то причине ваш необработанный образец не возвращал никаких результатов, которые он выполнял в течение нескольких минут, но ничего не было зафиксировано. Мне пришлось разбить ваш пример на мелкие части, чтобы понять концепцию.

Я сохранил основную строку, которая выполняет начальный синтаксический анализ, оставил ее в формате matchinfo.

$strLogEvents = select-string -path \\$Cmpname\c$\ProgramData\IS\Logs\DMS\outlook.* -pattern '(doFolderDocSearch ends, duration)|(doDocSearch ends, duration)' 

они прошли Matchinfo.Line во второй строке выбора, которая имеет текстовый текст и работает быстро.

$report = $strLogEvents | select-string -Inputobject {$_.line} -pattern ('(?<date>.+? .+?) ' + '(?<time>.+?) .+? ' + '(?<syscall>doFolderDocSearch|doDocSearch) ends, duration ' + '(?<duration>.+?) ms') | %{ 
    $g = $_.matches[0].groups 
    @{ 
     computer = $Cmpname 
     date = $g['date'].value 
     time = $g['time'].value 
     syscall = $g['syscall'].value 
     duration = $g['duration'].value 
    } 
} 
Смежные вопросы