Windows 이벤트 로그 중급 진단, PowerShell·wevtutil로 원인 범위 좁히는 법

Windows 이벤트 로그 진단을 위해 서버와 컴퓨터 로그를 점검하는 기술 작업 환경

AI를 활용하여 생성한 이미지입니다.

Windows 이벤트 로그는 오류가 난 뒤 한꺼번에 훑는 자료가 아니라, 문제가 생긴 범위를 좁히는 기록이에요.[1] 이벤트 ID 하나만 검색해 원인을 단정하면 같은 증상을 반복해서 만날 수 있습니다.[1] 먼저 어느 로그와 공급자(provider)가 움직였는지 확인하고, 시간·수준·이벤트 ID로 범위를 줄인 뒤 XML이나 PowerShell 객체로 세부 조건을 붙이는 순서가 안전해요.[1]

이벤트 뷰어보다 먼저 범위를 정하기

이벤트 로그에는 Application, System, Security처럼 성격이 다른 채널이 있고, 각 이벤트는 공급자가 기록합니다.[1] Microsoft의 이벤트 로깅 구조에서도 이벤트는 애플리케이션과 서비스가 이벤트 공급자로 등록되고, 로그 채널에 기록되는 방식으로 설명돼요.[3] 같은 “앱이 멈췄다”는 증상도 Application 로그의 애플리케이션 오류일 수 있고, System 로그의 디스크·서비스·드라이버 문제일 수도 있어요.[1]

처음부터 모든 로그를 열지 말고 다음 세 가지를 적어 두세요.[1]

  • 문제가 시작된 시각과 마지막으로 정상 작동한 시각
  • 영향을 받은 기능의 이름과 함께 바뀐 드라이버·업데이트·설정
  • 사용자가 본 증상과 재현 조건

이 기록이 있으면 이벤트를 최신순으로 훑는 대신 “문제가 시작된 5분 안에 System에서 Error가 발생했는가”처럼 질문을 만들 수 있어요.[1] 이벤트 ID는 출발점이지 판결문이 아닙니다.[1] 같은 ID라도 메시지의 세부 값과 직전·직후 이벤트가 다를 수 있어요.[1]

PowerShell로 최근 오류만 좁히기

Get-WinEvent는 로그 이름, 공급자, 최대 반환 수, XPath, 해시 테이블 필터를 받을 수 있습니다.[2] 예를 들어 System 로그에서 최근 Error와 Critical만 확인하려면 관리자 PowerShell에서 다음처럼 시작할 수 있어요.[1]

Get-WinEvent -FilterHashtable @{
  LogName = 'System'
  Level = 1,2
  StartTime = (Get-Date).AddHours(-2)
} -MaxEvents 100 |
  Select-Object TimeCreated, Id, ProviderName, LevelDisplayName, Message

Level 숫자는 로그의 수준을 좁히는 조건으로 사용하고, StartTime은 조사 시간을 제한합니다.[1] 아직 어떤 공급자가 문제인지 모를 때는 이 정도만 걸어 결과를 확보하세요.[1] -MaxEvents를 크게 잡으면 원인과 관계없는 기록이 섞여 읽기 어려워집니다.[1]

특정 공급자를 의심할 근거가 생기면 조건을 하나씩 추가해요.[1]

Get-WinEvent -FilterHashtable @{
  LogName = 'Application'
  ProviderName = 'Application Error'
  Id = 1000
  StartTime = (Get-Date).AddDays(-1)
} -MaxEvents 30 |
  Format-List TimeCreated, Id, ProviderName, Message

여러 조건을 동시에 넣었는데 결과가 0개라면 로그가 비어 있다는 뜻으로 단정하지 마세요.[1] 공급자 이름이나 이벤트 ID가 실제 기록과 다를 수 있고, 해당 로그가 다른 채널에 남았을 수도 있어요.[1] 먼저 Get-WinEvent -ListLog * | Select-Object LogName, IsEnabled, RecordCount로 채널 상태를 확인한 뒤 조건을 하나씩 되돌리는 편이 낫습니다.[1]

FilterHashtable과 XPath를 나누는 기준

FilterHashtable은 로그 이름, ID, 공급자, 수준, 시간처럼 자주 쓰는 조건을 읽기 좋은 형태로 묶을 때 편합니다.[1] 반면 이벤트 XML의 특정 데이터 필드까지 검사해야 하면 -FilterXPath나 -FilterXml이 더 적합해요.[1] Microsoft 문서도 Get-WinEvent에 -FilterXPath, -FilterXml, -FilterHashtable을 각각 제공하고, 파일 로그를 읽는 -Path도 따로 설명합니다.[2]

예를 들어 System 로그에서 특정 이벤트 ID와 최근 시각을 XPath로 제한하려면 다음처럼 쓸 수 있어요.[1]

$since = (Get-Date).AddHours(-1).ToUniversalTime().ToString('o')
$xpath = "*[System[(EventID=41) and TimeCreated[@SystemTime >= '$since']]]"
Get-WinEvent -LogName System -FilterXPath $xpath -MaxEvents 50 |
  Select-Object TimeCreated, Id, ProviderName, Message

XPath에서 시간 형식이나 이벤트 데이터 이름을 잘못 쓰면 결과가 없을 수 있어요.[1] 처음에는 ID와 채널만 넣고, 결과가 확인된 다음 데이터 필드를 추가하세요.[1] 조건을 복잡하게 만드는 것보다 조사 단계마다 결과를 저장하는 편이 재현하기 쉽습니다.[1]

오래된 이벤트부터 시간순으로 읽어야 할 때는 -Oldest를 사용하고, 로그 파일을 보관해 다른 PC에서 분석할 때는 -Path로 evtx 파일을 읽을 수 있어요.[1] 원본 PC에서 재현이 끝난 뒤 로그를 복사해 분석하면 추가 조작으로 기록이 바뀌는 위험을 줄일 수 있습니다.[1]

wevtutil로 채널 상태와 원본을 확인하기

PowerShell이 제대로 열리지 않거나 이벤트 뷰어가 느릴 때는 Windows 기본 명령인 wevtutil이 유용합니다.[1] Microsoft 문서에 따르면 wevtutil el은 로그 이름을 나열하고, wevtutil gl <Logname>은 활성화 여부·최대 크기·저장 경로를 보여 줍니다.[1]

wevtutil el
wevtutil gl System
wevtutil gl Application /f:xml

이 결과로 로그가 활성화되어 있는지, 최대 크기와 실제 저장 경로가 무엇인지 확인할 수 있어요.[1] 저장 경로가 바뀌었거나 디스크 공간이 부족한 PC에서는 이벤트가 기대한 위치에 없을 수 있습니다.[1]

특정 시간이나 ID를 명령줄에서 빠르게 뽑고 싶다면 qe를 사용합니다.[1]

wevtutil qe System /q:"*[System[(Level=2) and (EventID=41)]]" /f:text /c:20 /rd:true

wevtutil qe는 이벤트를 읽고, /q는 XPath 필터를 적용하며, /c는 반환 개수, /rd:true는 최신 이벤트부터 읽는 조건이에요.[1] /f:xml을 쓰면 이벤트 구조를 보존할 수 있어 후속 분석이나 전달에 더 적합합니다.[1]

지우기보다 먼저 내보내기

로그가 커서 정리해야 하더라도 바로 지우지 마세요.[1] wevtutil epl은 로그나 필터 결과를 파일로 내보낼 수 있고, wevtutil cl은 로그를 지우되 /bu로 지우기 전 백업 파일을 만들 수 있습니다.[1]

wevtutil epl System C:\Temp\System-before-clean.evtx /ow:true
wevtutil cl System /bu:C:\Temp\System-before-clear.evtx

이 작업은 관리자 권한과 충분한 저장 공간이 필요해요.[1] 장애 분석 중인 PC라면 로그를 지운 뒤 재현 결과와 과거 기록을 구분할 수 없게 되므로, 파일을 별도 저장장치나 승인된 공유 위치에 먼저 보관하세요.[1] wevtutil 문서도 내보내기와 지우기 기능을 별도 명령으로 나누고, 지우기 전에 /bu로 백업할 수 있다고 설명합니다.[1]

결과가 없을 때 점검할 것

첫째, 시각을 확인하세요. PowerShell 출력의 TimeCreated와 XML의 SystemTime 표현이 달라 보일 수 있어요.[1] PC 시간대가 잘못되어 있으면 사용자가 본 시각과 로그 시각이 어긋납니다.[1]

둘째, 채널을 바꾸세요. 앱 오류가 Application에만 남는다는 보장은 없습니다.[1] 서비스 시작 실패는 System과 해당 서비스의 별도 운영 로그에 함께 기록될 수 있어요.[1]

셋째, 공급자 이름을 실제 값으로 복사하세요.[1] 화면에 보이는 제품 이름과 ProviderName은 다를 수 있습니다.[1]

넷째, 이벤트 하나만 보지 마세요.[1] 장애 직전의 Warning, 서비스 종료, 디스크 오류가 원인에 가까울 수 있습니다.[1] 같은 시각의 다른 채널을 1~2분 범위로 모아 시간순으로 정리하면 인과관계를 더 쉽게 볼 수 있어요.[1]

중급자용 점검 순서

1. 증상과 시작 시각을 기록하고 조사 시간대를 정해요.[1] 2. Get-WinEvent -ListLog * 또는 wevtutil el로 채널 이름을 확인해요.[1] 3. PowerShell FilterHashtable로 로그·수준·시간을 먼저 좁혀요.[1] 4. 공급자와 이벤트 ID가 확인되면 ProviderName, Id, -MaxEvents를 추가해요.[1] 5. 이벤트 데이터까지 필요할 때만 XPath를 붙여요.[1] 6. 원본 로그를 evtx로 내보낸 뒤 결과를 공유하거나 보관해요.[1] 7. 백업 없이 로그를 지우지 말고, 정리 후에는 같은 조건으로 재현 여부를 다시 확인해요.[1]

이 순서를 지키면 “이벤트 ID 41이 있으니 전원 문제”처럼 빠른 결론을 피할 수 있어요.[1] 로그는 원인을 대신 판단해 주지 않지만, 시간과 범위를 정확히 통제하면 점검해야 할 후보를 크게 줄여 줍니다.[1]

Sources

[1] https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/wevtutil — https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/wevtutil [2] https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.diagnostics/get-winevent?view=powershell-7.5 — https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.diagnostics/get-winevent?view=powershell-7.5 [3] https://learn.microsoft.com/en-us/windows/win32/eventlog/event-logging — https://learn.microsoft.com/en-us/windows/win32/eventlog/event-logging

함께 읽을 글