Как передать журнал событий Windows в командную строку?

Я хочу сделать эквивалент:

tail -f

в Windows. Я прочитал это, но похоже, что нет возможности передавать журнал событий в потоковом режиме, поэтому он работает в бесконечном цикле и отображает события по мере их возникновения в командной строке. Есть ли какая-либо встроенная опция/флаг команды для этого в Windows?

Возможно, это неправильное решение от wevutil, но попробуйте что-нибудь вроде вот этого

Daemon-5 04.09.2024 14:35
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
1
54
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Эквивалентом tail -f является Get-Content -Wait. Но это не помогает, потому что вам все равно нужны ваши события в текстовом файле. Windows хранит свои события в файлах .evtx по адресу C:\Windows\System32\winevt\Logs, и они являются двоичными.

В качестве обходного пути вы можете периодически печатать последние x событий:

function Get-WinEventTail {

    param(
        $LogName,
        $MaxEvents = 20
    )

    while ($true) {
        Get-WinEvent -LogName $LogName -MaxEvents $MaxEvents | Select-Object TimeCreated, Message
        Start-Sleep -Seconds 1
    }
}

Get-WinEventTail -LogName System

Более сложный подход — использовать EventLogWatcher для записи входящих событий в текстовый файл и последующего отслеживания этого файла:

function Write-WinEventsToTempFile {

    param(
        $LogName
    )

    try {
        $logFile = New-TemporaryFile
        $query = [System.Diagnostics.Eventing.Reader.EventLogQuery]::new($LogName,[System.Diagnostics.Eventing.Reader.PathType]::LogName)
        $watcher = [System.Diagnostics.Eventing.Reader.EventLogWatcher]::new($query)
        $watcher.Enabled = $true
        $action = {
            $myEvent = Get-WinEvent -LogName $eventArgs.EventRecord.LogName | Where-Object {$_.RecordId -eq $eventArgs.EventRecord.RecordId}
            "[$($myEvent[0].TimeCreated)]: $(($myEvent[0].Message -replace '\r\n', '') -replace '\t|\s{2,}', ' ')" | Out-File $event.MessageData -Append
        }
        $job = Register-ObjectEvent -InputObject $watcher -SourceIdentifier WriteWinEventsToTempFile -EventName 'EventRecordWritten' -MessageData $logFile -Action $action
        Write-Host "Use `"Get-Content '$($logFile.FullName)' -Wait`" in another PowerShell window to tail the log. Press Ctrl+C, if you are done..."
        Wait-Event -SourceIdentifier WriteWinEventsToTempFile
    } finally {
        Remove-Job $job -Force
        Remove-Item $logFile
    }
}

Write-WinEventsToTempFile -LogName System

Get-WinEventTail рискует исчерпать место в стеке из-за рекурсивных вызовов; кроме того, вы каждый раз безоговорочно получаете последние N записей, что приводит к созданию дубликатов. Функция Write-WinEventsToTempFile многообещающая, но нет необходимости во временном файле: вместо этого обходитесь без аргумента -Action, вызывайте Wait-Event в бесконечном цикле и используйте ее выходные данные для извлечения и вывода вновь добавленных записей журнала событий.

mklement0 04.09.2024 12:52
Ответ принят как подходящий

Решение на основе [System.Diagnostics.Eventing.Reader.EventLogWatcher] в ответе stackprotector многообещающе, но несколько громоздко из-за необходимости использования временного файла, который необходимо читать отдельно.

Этого можно избежать с помощью следующей функции Trace-WinEvent, которая передает любые новые добавленные записи событий непосредственно в конвейер:

function Trace-WinEvent {

  param(
    [Parameter(Mandatory)] [string] $LogName
  )

  $sourceId = 'TraceWinEvent' # self-chosen
  try {
    $query = [System.Diagnostics.Eventing.Reader.EventLogQuery]::new($LogName, 'LogName')
    $watcher = [System.Diagnostics.Eventing.Reader.EventLogWatcher]::new($query)
    $watcher.Enabled = $true
    Write-Verbose "Registering for EventLogWatcher events for the '$LogName' log..."
    Register-ObjectEvent -InputObject $watcher -SourceIdentifier $sourceId -EventName EventRecordWritten
    Write-Verbose 'Waiting for such events indefinitely; use Ctrl+C to stop...'
    while ($true) {
      $evt = Wait-Event -SourceIdentifier $sourceId
      $evt | Remove-Event
      # Extract the event record.
      $evtRec = $evt.SourceEventArgs.EventRecord
      # Add a .Message NoteProperty member and output the decorated record.
      $evtRec | Add-Member -PassThru Message $evtRec.FormatDescription()
    }
  }
  finally {
    Unregister-Event $sourceId
  }
}

Вызовите его, например, следующим образом:

# Trace (monitor) the Application event log for newly created records 
# and also capture them in variable $records.
# -Verbose provides verbose feedback.
# Use Ctrl-C to stop.
Trace-WinEvent Application -OutVariable records -Verbose 

Пример вывода:

Примечание:

  • Потоковая передача в конвейер не только обеспечивает мгновенный вывод на консоль, но также позволяет программную обработку записей, которые являются экземплярами [System.Diagnostics.Eventing.Reader.EventLogRecord], в конвейере.

  • Чтобы прекратить отслеживание (мониторинг), нажмите Ctrl+C.

  • Реализация основана на:

    • Вызов Register-ObjectEvent без блока сценария -Action, что ставит PowerShell в очередь событий для извлечения по требованию.

    • Это извлечение по требованию выполняется в бесконечном цикле, который вызывает Wait-Event для получения ожидающих событий по одному в блокирующем режиме.

    • Поскольку форматирование экземпляров EventLogRecord в PowerShell для отображения зависит от наличия свойства .Message ETS (типа NoteProperty, которым Get-WinEvent автоматически украшает свои выходные объекты), приведенный выше код вручную декорирует каждый экземпляр, извлеченный из объекта события. таким образом, с помощью метода .FormatDescription(), и выводит декорированный экземпляр в конвейер.


[*]

Рад слышать, что это помогло, @morpheus; Не за что.

mklement0 05.09.2024 01:24

Другие вопросы по теме