Windows WMI 이벤트 및 PowerShell 작업 가이드

알고 계셨나요? Windows에서 거의 모든 작업을 모니터링할 수 있다는 사실을요? 아니요, 특별한 소프트웨어를 구매할 필요는 없습니다. 인프라는 서비스 시작 및 중지, 파일 또는 폴더 생성 등 이벤트를 Windows 관리 인터페이스(WMI) 이벤트를 통해 이미 모니터링합니다.

WMI 이벤트는 PowerShell 특정 기능은 아니지만, WMI 이벤트를 활용하고 유용한 도구를 만드는 가장 쉬운 방법 중 하나가 PowerShell입니다. 이 단계별 자습서에서는 PowerShell을 사용하여 WMI 이벤트를 활용하는 방법을 배우고 유용한 모니터링 도구를 구축하는 기술을 습득할 수 있습니다!

시작해 봅시다!

전제 조건

이 실습 자습서에서는 많은 데모를 볼 수 있습니다. 데모 중 어느 것이든 따라 하려면 다음이 필요합니다:

  • Windows 7+ 또는 Windows Server 2012+ – 이 자습서에서는 Windows Server 2019를 사용합니다.
  • 로컬 관리자 그룹의 사용자로 로그인되어 있어야 합니다.
  • Windows PowerShell 5.1 또는 PowerShell 6+ – 이 자습서에서는 PowerShell v7.1.2를 사용합니다.

WMI와 CIM 이해

WMI 이벤트에 대해 자세히 들어가기 전에, 그것들이 구축된 인프라를 먼저 이해하는 것이 중요합니다. 이 자습서는 WMI에 대해 자세히 다루지는 않지만, 언제든지 Microsoft의 WMI 문서를 참조하여 자세히 알아볼 수 있습니다.

WMI 및 관련 데이터 모델 Common Information Model (CIM)은 Windows에 내부 작동 및 실행 중인 것과 관련된 리포지토리에 필요한 거의 모든 정보를 저장하는 내장 모델입니다.

WMI와 CIM은 로컬 및 원격적으로 Windows를 관리하는 데 사용되는 강력한 도구입니다. WMI 또는 CIM을 사용하여 관리자는 설치된 응용 프로그램, 서비스 상태, 파일 시스템의 파일 등 Windows 시스템의 정보를 조회할 수 있습니다.

WMI와 CIM은 많은 기업 모니터링 솔루션에서 운영 체제 및 응용 프로그램 상태 정보를 수집하는 방법입니다. 그러나 WMI를 활용하기 위해 비싼 모니터링 도구를 구매할 필요는 없습니다. PowerShell을 사용할 수 있습니다!

두 가지 기본 요소부터 시작하고, 계속 진행하면 다른 필요한 요소를 배우게 될 것입니다:

  • 클래스: 클래스는 응용 프로그램(예: PowerShell)이 데이터를 읽고 업데이트하는 데 사용할 수 있는 이벤트 및 속성입니다. 클래스는 네임스페이스 내에 위치합니다.
  • 네임스페이스: 네임스페이스는 WMI 관련 클래스를 포함하는 컨테이너입니다. 이것을 그림 관련 콘텐츠를 보관하는 내 사진 폴더로 생각해보세요. 여러 네임스페이스가 있으며, 가장 일반적인 것은 대부분의 OS 클래스를 보유하는 CIMv2입니다. 그러나 모든 네임스페이스는 큰 단일 네임스페이스 Root 하위에 위치합니다.
WMI Architecture

WMI 대 CIM

WMI 및 CIM은 모두 Windows 시스템의 저장소와 상호 작용하고 WMI 이벤트를 처리하는 방법입니다(나중에 자세히 설명됨). 그러나 두 방법에는 주로 원격으로 관리자가 상호 작용하는 방식이 몇 가지 차이점이 있습니다.

WMI는 Windows NT4에서 시작되었으며 저장소와 상호 작용하는 원래 (유일한) 방법이었습니다. WMI로 Windows 시스템을 관리할 때 Windows는 Distributed Component Object Model (DCOM)을 사용합니다. DCOM은 Windows 기계의 데이터 저장소 내에서 정보를 노출하기 위해 WMI가 사용하는 원격 프로토콜입니다.

네트워크 상에서 작동하려면 DCOM은 Remote Procedure Call (RPC)를 사용합니다. 네트워크를 통해 통신하기 위해 RPC는 동적 포트 범위를 사용하며 이는 방화벽 및 네트워크 주소 변환 (NAT) 장치에 대한 도전일 수 있습니다.

RPC에 문제가 있으면 Dynamic Ports로 RPC 연결 테스트 문서를 확인해보세요.

마이크로소프트는 윈도우의 데이터 저장소와 상호 작용하는 더 현대적인 방법을 제공하기 위해 CIM 기술을 활용하기로 결정했습니다. RPC 대신 CIM은 원격 관리에 훨씬 더 적합한 HTTP 프로토콜인 WS-MAN (웹 서비스 관리용)을 사용합니다.

이 문서와 기타 문서에서는 WMI와 CIM을 상호 교환하여 사용할 수 있습니다. 두 관리 방법이 상호 작용하는 데이터 저장소를 일반적으로 WMI 저장소라고 합니다. 거의 모든 용어는 WMI를 참조하며, CIM은 주로 PowerShell cmdlet에서 사용됩니다.

WMI 대 CIM과 PowerShell

당신은 PowerShell에서 WMI와 CIM을 사용할 수 있는 몇 가지 옵션을 가지고 있습니다. PowerShell은 데이터 저장소와의 상호 작용을 지원합니다. PowerShell에서 Get-Command 명령을 실행하면 Get-WmiObjectInvoke-WmiMethodRemove-WmiObjectRegister-WmiEvent, 및 Set-WmiInstance와 같은 다양한 Wmi cmdlet을 볼 수 있습니다.

Windows PowerShell 3 이상을 실행 중인 경우 (반드시 그렇게 해야 합니다!), Get-CimInstance, Get-CimClass, 및 Remove-CimInstance와 같은 유사한 이름의 cmdlet도 볼 수 있습니다.

어떤 PowerShell cmdlet을 사용해야 할까요? 답은 간단합니다. CIM cmdlet을 사용하세요. CIM은 마이크로소프트가 주력으로 삼고 있는 새로운 표준입니다. WMI cmdlet은 심지어 PowerShell Core에서도 사용할 수 없습니다!

WMI 쿼리: 기본 사항

WMI 이벤트를 알아보기 전에 PowerShell에서 WMI를 쿼리하는 방법을 이해해야 합니다. WMI 리포지토리에서 정보를 쿼리하는 것은 WMI 데이터의 가장 일반적인 사용법입니다.

PowerShell에서 WMI 데이터를 쿼리하려면 Get-CimInstance cmdlet을 사용하세요. 이 cmdlet에는 WMI 데이터를 쿼리하는 몇 가지 다른 방법이 있습니다. 그러나 이 튜토리얼은 Query 매개변수에 초점을 맞출 것입니다. Query 매개변수를 사용하면 Windows Query Language (WQL) 쿼리를 제공하여 WMI를 쿼리할 수 있습니다.

예를 들어, Win32_Service 클래스에서 모든 WMI 인스턴스를 찾으려는 경우입니다. SQL과 유사하게 아래와 같은 쿼리 Select * from Win32_Service를 사용할 것입니다. 별표 (*)는 WMI에 각 인스턴스의 모든 속성을 반환하도록 지시합니다.

Get-CimInstance -Query 'Select * from Win32_Service'
Getting Windows Services using WMI Query

위의 예에서는 모든 Win32_Service 클래스의 서비스 인스턴스를 찾았지만, 일부만 찾고 싶은 경우는 어떻게 할까요? 그럴 경우 WHERE 절을 사용합니다. WHERE 절은 특정 조건과 일치하는 인스턴스만 반환하는 필터를 생성합니다.

The WHERE clause는 Get-CimInstance이 특정 값과 일치하는 인스턴스 속성만 반환하도록 지시합니다. 예를 들어, 아마도 State 속성이 Running인 서비스 인스턴스만 찾고 싶을 수 있습니다. 그렇다면 아래와 같이 WHERE 절을 정의할 것입니다: Where State='Running'.

Get-CimInstance -Query "Select * from Win32_Service Where State='Running'"

아래에서 볼 수 있듯이 Get-CimInstanceState 속성이 Running인 서비스 인스턴스만 반환했습니다.

Returning only service that are in Running state

WMI 이벤트: WMI의 동작

WMI에는 Windows의 수천 개 항목에 대한 정보가 포함된 큰 저장소가 있습니다. 위와 같이 쿼리하여 이 정보에 액세스할 수 있지만 또 다른 잘 알려지지 않은 기능이 있습니다. WMI 이벤트입니다.

Windows에서는 언제든지 수백 개의 이벤트가 발생할 수 있습니다. Windows의 여러 기능을 사용하여 파일을 생성하거나 서비스를 중지하고 시작하거나 소프트웨어를 설치하는 경우 등 어떠한 조치를 취하면 WMI 이벤트가 트리거될 것입니다.

Windows에서 수행되는 모든 작업은 기본적으로 WMI 이벤트를 통해 노출될 수 있습니다. Windows에서 조치를 취하면 내부 인프라를 통해 이벤트가 트리거됩니다. 기본적으로 이러한 이벤트를 볼 수 없습니다. 이러한 이벤트를 보려면 구독해야 합니다.

PowerShell로 서비스 모니터링 스크립트 작성하기

WMI 이벤트가 작동하는 방법을 보여주기 위해 많은 정보를 지루하게 설명하는 대신 유용한 도구를 만들어 보겠습니다. WMI 이벤트는 Windows에서 이벤트가 발생할 때 발생하므로 이를 사용하여 유용한 모니터링 도구를 만들 수 있습니다.

아마도 중요한 서버에서 Windows 서비스 상태가 변경될 때 메시지를 로그 파일에 작성하고 싶을 것입니다. 그럼 해당 작업이 발생할 때 트리거되는 WMI 이벤트에 구독할 수 있습니다. 이벤트에 구독하고 이벤트가 트리거되면 PowerShell로 파일에 로그를 기록하거나 이메일을 보내는 등의 작업을 수행할 수 있습니다.

일부 비싼 모니터링 솔루션을 구매하는 대신 간단한 PowerShell 스크립트가 좋은 가난한 사람의 모니터링 도구가 될 수 있습니다! 준비가 되었다면 PowerShell 콘솔을 열고 시작해 봅시다!

CIM 클래스 찾기

WMI 내에서 정적 인스턴스와 마찬가지로 이벤트도 클래스에 포함되어 있습니다. 이러한 클래스에는 위에서 쿼리한 모든 정적 데이터와 해당 인스턴스의 변경 사항이 트리거되는 위치가 포함되어 있습니다. Microsoft 문서에는 모든 CIM 클래스 목록을 찾을 수 있습니다.

모든 CIM 클래스를 찾으려면 매개변수 없이 Get-CimClass cmdlet을 실행합니다. Get-CimClass cmdlet은 기본적으로 ROOT/cimv2 네임스페이스에 있는 모든 클래스를 반환합니다. ROOT/cimv2 네임스페이스는 거의 모든 중요한 Windows 클래스가 저장된 “주” 네임스페이스입니다.

Get-CimClass

아래에서 많은 클래스가 반환되는 것을 볼 수 있습니다.

Finding the CIM Class

혹시 몇 가지 조사를 한 후에 Windows 서비스가 모두 Win32_Service에 저장되어 있다는 것을 깨닫게 되었나요? 그래서 클래스 이름을 알면 아래에 표시된대로 ClassName 매개변수를 사용하여 이름을 지정하세요.

Get-CimClass -ClassName Win32_Service
Get CimClass Parameter

CIM 클래스 속성 찾기

찾을 클래스를 알게 되면 어떤 속성을 살펴볼지 결정해야 합니다. 인스턴스 속성의 값이 변경되면 (또는 전체 인스턴스가 생성 또는 제거되면) 이벤트가 발생합니다. 그 상태 변화를 잡아내려면 해당 상태 변경을 알아야 합니다. 이를 위해서는 모니터링하려는 속성을 알아야 합니다.

해당 속성을 찾으려면 이전 섹션에서 쿼리한 CIM 클래스 인스턴스의 CimClassProperties PowerShell 객체 속성을 검사하세요.

(Get-CimClass -ClassName win32_Service).CimClassProperties

아래에서 그 속성 중 하나가 State 속성임을 알 수 있습니다.

Some of the Win32_Service Properties

이제 CIM 클래스 및 속성을 모니터링하려고 하는 것을 알게 되었으니 WMI 이벤트에 가입할 시간입니다!

WMI 이벤트 구독 생성: 고수준 개요

WMI 이벤트 구독 생성은 이전에 만들어본 적이 없다면 혼란스러운 작업일 수 있습니다. 작업을 진행하는 데 도움이 되도록 나무보다 먼저 숲을 살펴보고 기본 단계를 개요로 설명해 보겠습니다.

WMI 이벤트 구독 생성에는 대략 네 단계가 필요합니다:

  1. WQL 쿼리 작성하기 – 정적 데이터를 쿼리할 때와 마찬가지로 보고 싶은 WMI 이벤트 유형과 일치하는 WQL 쿼리를 작성해야합니다. 그러나 데이터 저장소를 쿼리하는 것과 달리, 시스템 클래스와 검사 주기(나중에 설명함과 관련된)와 같이 쿼리에 약간 더 복잡한 구성 요소를 사용해야합니다.
  2. 이벤트 필터 생성 – WQL 쿼리를 작성한 후에는 이벤트 필터를 생성해야합니다. 이벤트 필터는 WQL 쿼리를 CIM에 등록합니다.
  3. 소비자 생성 – 소비자는 이벤트 필터 쿼리가 클래스에서 변경 사항을 반환할 때 취해야 할 작업을 정의합니다. 예를 들어, 서비스 상태가 시작되거나 중지되거나 생성되거나 제거될 때마다 소비자가 작업을 트리거합니다.
  4. 이벤트 필터를 소비자에 바인딩하기 – Windows WMI 쿼리를 소비자에 연결하는 접착제입니다. 바인딩은 이벤트 필터가 일치하는 것을 수신할 때 소비자에게 알립니다.

이러한 각 항목을 함께 묶으면 구독을 만듭니다.

Basic example of a WMI event subscription

WQL 쿼리 작성

A WQL query for a WMI event looks a bit different than performing a simple query with Get-CimInstance. Below you’ll find a typical WMI event query.

Select * from <system class> within <checking cycle> where TargetInstance ISA '<class name>'

처음에는 WQL 쿼리가 복잡해 보일 수 있으므로, 각 구성 요소가 어떻게 작동하는지 분해하고 이해해보겠습니다.

시스템 클래스

Get-CimInstance 예제에서 Win32_Service 클래스의 인스턴스에 변경 사항이 발생할 때 알림을 받고 싶다는 것을 발견했습니다. 여전히 이 클래스가 필요하지만 다음과 같은 WQL 쿼리 대신에:

Select * from Win32_Service

대신, 아래와 같이 쿼리가 시작됩니다. 질의하려는 주요 클래스는 알림을 받길 원하는 인스턴스를 포함하는 클래스가 아닙니다. 대신, 해당 클래스는 시스템 클래스입니다.

Select * from <system class>

시스템 클래스는 이벤트가 발생하는 변경 유형을 나타내는 내부 클래스입니다. WMI 이벤트에는 네 가지 유형의 시스템 클래스가 있습니다:

  • InstanceModificationEvent 클래스의 인스턴스에서 속성 값 변경을 확인합니다. 이 클래스는 원하는대로 Win32_Service 클래스의 인스턴스(서비스)에서 Status 속성 값을 모니터링하려고하기 때문에 사용할 것입니다.
  • InstanceCreationEvent – 새 인스턴스를 확인합니다. 예를 들어, 새로 생성된 서비스를 모니터링하려면이 시스템 클래스를 사용할 수 있습니다.
  • InstanceDeletionEvent – 제거된 인스턴스를 확인합니다. 예를 들어, 제거된 서비스를 모니터링하려면이 시스템 클래스를 사용할 수 있습니다.
  • InstanceOperationEvent – 이 시스템 클래스는 변경, 생성 및 삭제 모든 이벤트 유형을 확인합니다.

모니터링 스크립트의 경우, WQL 쿼리의 시작은 다음과 같이 보일 것입니다.

Select * from __InstanceModificationEvent

WMI 시스템 클래스 이름은 항상 두 개의 밑줄 (__)로 시작하고 클래스 이름이 뒤따릅니다.

확인 주기

다음으로 확인 주기가 있습니다. 확인 주기에는 within 키워드와 초 단위로 표시된 폴링 간격을 나타내는 값이 포함됩니다.

within <checking cycle>

WMI 이벤트는 실시간이 아니므로 변경 사항을 확인하기 위해 구독의 특정 간격을 정의해야 합니다. 예를 들어, 확인 주기를 10으로 설정하면 구독이 마지막 폴링 주기로부터 10초마다 변경 사항을 확인합니다. 변경 사항이 발견되면 소비자가 트리거됩니다.

인스턴스가 폴링 간격 내에 시스템 클래스에 따라 변경, 생성 또는 제거되면 변경 사항이 감지되지 않습니다! 필요한 빈도를 고려하되 CPU 및 메모리 친화적인지 확인하십시오!

튜토리얼의 서비스 모니터링 예제에서는 Windows 서비스의 변경 사항을 확인하기 위해 확인 주기를 10으로 설정합니다. WQL 쿼리가 커지고 있습니다!

Select * from __InstanceModificationEvent within 10

필터

마지막으로 WQL 쿼리를 완성하기 위해 시스템 클래스에서 반환되는 인스턴스를 제한하는 필터를 정의해야 합니다. 이 필터를 아래 양식에 정의해야 합니다. 이 경우 모니터링하려는 CIM 클래스는 TargetInstance라고 합니다.

where Targetinstance ISA '<class name>'

ISA는 지정된 클래스의 하위 클래스에 쿼리를 적용하는 연산자입니다.

튜토리얼이 Windows 서비스를 모니터링하는 구독을 작성하고 있으므로 아래와 같이 필터를 작성합니다:

where Targetinstance ISA 'Win32_Service'

다음과 같이, 필터는 모든 Win32_Service 인스턴스를 찾습니다. 특정 서비스와 같은 단일 속성만 모니터링하려면 AND 연산자를 사용하면 됩니다.

where Targetinstance ISA 'win32_Service' AND Targetinstance.name='bits'

AND 또는 OR 연산자를 사용하여 다른 조건을 추가하여 더 정확한 결과를 얻을 수 있습니다.

튜토리얼 필터(및 전체 쿼리)는 이제 아래 코드 스니펫과 같이 완료되었습니다.

Select * from __InstanceModificationEvent within 10 where Targetinstance ISA 'win32_Service' AND Targetinstance.name='bits'

이벤트 필터 만들기

이제 쿼리 필터가 있으므로 나머지 과정은 훨씬 쉽게 이해할 수 있습니다! 이제 그 쿼리를 사용하기 위해 이벤트 필터를 만들어야 합니다. 이벤트 필터는 사실 Root/subscription 네임스페이스 내부의 __EventFilter 클래스의 다른 CIM 인스턴스입니다.

아래에는 필요한 모든 것이 포함된 코드 스니펫이 있습니다. 아래 스크립트는 WQL 쿼리를 $FilterQuery 변수에 할당합니다. 그런 다음 이벤트 필터가 필요로 하는 각 속성과 값이 포함된 해시 테이블을 만듭니다. 그런 다음 이벤트 필터를 생성하기 위해 New-CimInstance cmdlet을 실행합니다. 생성된 CIM 인스턴스 객체는 나중에 사용하기 위해 변수($CIMFilterInstance)에 저장됩니다.

그 다음, Get-CimInstance를 실행하여 __EventFilter의 새 CIM 인스턴스가 생성되었는지 확인하십시오.

$FilterQuery="Select * from __InstanceModificationEvent within 10 where TargetInstance ISA 'Win32_Service'"
$CIMEventFilterProperties = @{
	## 이벤트 필터의 이름. 관련이 있는 것이면 무엇이든 가능합니다.
	Name="MyServiceFilter"
	## 대상 클래스에 대한 네임스페이스, 예를 들어, 대상 클래스가
	## **Win32_Service**인 경우 Root/CIMv2입니다.
	EventNameSpace="Root/CIMV2"
	## 쿼리 언어, 일반적으로 **WQL**입니다.
	QueryLanguage="WQL"
	## 사용할 쿼리.
	Query=$FilterQuery
}

$CIMFilterInstance=New-CimInstance -ClassName __EventFilter -Namespace "Root/SubScription" -Property $CIMEventFilterProperties

이제, 새로운 __EventFilter CIM 인스턴스가 생성되었는지 확인하려면 Get-CimInstance를 실행하십시오.

Get-CimInstance -Namespace root/subscription -ClassName __EventFilter
Event Filter Created Successfully and registered the Windows WMI Query

소비자 생성

다음으로, Windows가 WMI 이벤트를 트리거할 때 발생할 작업 또는 작업을 만드는 시간입니다. 소비자를 생성할 때는 트리거하려는 작업의 유형에 따라 몇 가지 옵션이 있습니다.

악성 이진 파일로 EXE를 대체하는 것을 방지하기 위해 실행 파일의 ACL이 올바르게 정의되어 있는지 확인합니다.

이 튜토리얼에서는 WQL 쿼리에서 일치하는 서비스가 변경될 때 로그 파일에 쓰기 위해 LogFileEventConsumer 소비자 유형을 사용하겠습니다.

$CIMCOnsumerProperties = @{
	## 스크립트가 **Root/Subscription** 네임스페이스에 등록할 이름
	Name="MyServiceConsumer"
	## 이벤트가 트리거될 때 로그가 작성되는 파일 경로와 이름
	FileName="C:\\MyCIMMonitoring.txt"
	## 로그에 작성할 텍스트. 변수를 추가하려면
	## %TargetInstance.WMIProperty%를 사용하십시오. 이 예제에서는 **Caption**과 **State
	##**을 사용합니다.
	Text = "The Service %TargetInstance.Caption% has been Changed: %TargetInstance.State%"
}
$CIMEventConsumer=New-CimInstance -ClassName LogFileEventConsumer -Namespace 'ROOT/subscription' -Property $CIMCOnsumerProperties

## 다른 컨슈머 예제
######################
## NTEventLogEventConsumer
######################
## $Template = @(
##  '서비스 %TargetInstance.Caption%이(가) 변경되었습니다: %TargetInstance.State%'
##)
##$CIMCOnsumerProperties=@{
## ## 컨슈머의 이름
##	Name="내이벤트로그컨슈머"
## ## 사용할 이벤트 ID
##	EventID =[UInt32] 7040
##  EventType는 다음 값 중 하나를 가질 수 있습니다
##    ## - **0**: 성공 이벤트
##    ## - **1**: 오류 이벤트
##    ## - **2**: 경고 이벤트
##    ## - **4**: 정보 이벤트
##    ## - **8**: 성공 감사 이벤트
##    ## - **16**: 실패 감사 이벤트
##  EventType=[UInt32] 1 #정보
## ## 이벤트 소스의 이름
##  SourceName="서비스 제어 관리자"
##  Category=[UInt16] 0
##  ## **InsertionStringTemplates**의 줄 수
##  NumberOfInsertionStrings =[UInt32] $Template.Length
##  ## Windows 이벤트 로그 레코드에 표시할 메시지 텍스트
##  InsertionStringTemplates = $Template
##}
## $CIMEventConsumer=New-CimInstance -ClassName NTEventLogEventConsumer -Namespace 'ROOT/subscription' -Property $CIMCOnsumerProperties

######################
## CommandLineEventConsumer
######################
##$CIMCOnsumerProperties=@{
##  ## 컨슈머에 대한 고유한 이름
##	Name="내시작앱컨슈머"
##  ## 이벤트 트리거 시 시작할 응용 프로그램의 경로 및 매개변수
##	CommandLineTemplate ='pwsh.exe c:\\myscript.ps1 -ServiceName %TargetInstance.name% -NewState %TargetInstance.State%'
##  ## (선택 사항) 일정 시간(초) 후에 응용 프로그램 종료. 서버 자원 보호에 유용합니다.
##  ## KillTimeout = 5 
##}
##$CIMEventConsumer=New-CimInstance -ClassName CommandLineEventConsumer  -Namespace 'ROOT/subscription' -Property $CIMCOnsumerProperties

######################
## SMTPEventConsumer
######################
## 이메일 메시지 본문
## $Message= '파일 서버가 변경되었습니다: %Targetinstance.Name% , %TargetInstance.Status%'

##$CIMCOnsumerProperties=@{
##	Name="내서비스-이메일컨슈머"
##	## 발신자의 이메일 주소
##	FromLine ='[email protected]'
##	## 수신자의 이메일 주소
##	ToLine = '[email protected]'
##	## 메시지를 전송할 SMTP 서버
##	SMTPServer = 'MySMTPServer.MyDomain.Com'
##	## 메시지 제목
##	Subject = '파일 서버 변경...'
##	Message= $Message
##}
##$CIMEventConsumer=New-CimInstance -ClassName SMTPEventConsumer   -Namespace 'ROOT/subscription' -Property $CIMCOnsumerProperties

각 소비자 클래스마다 고유의 매개변수가 있으므로 각 클래스에 대한 자세한 내용은 CimClassProperties를 확인하십시오. 예를 들어 (Get-CimClass -ClassName __NTEventLogEventConsumer).CimClassProperties를 참조하십시오.

소비자를 생성한 후에도 Get-Ciminstance로 존재 여부를 다시 확인하십시오.

Get-CimInstance -Namespace Root/Subscription -ClassName LogFileEventConsumer
Consumer Registered with the required parameters

이벤트 필터와 소비자를 결합하기

마침내 이 구독을 완료하고 이벤트 필터와 소비자를 결합하는 시간입니다! 결합을 생성한다는 것은 한 번 더 CIM 인스턴스를 생성한다는 것을 알 수 있습니다. 이번에는 __FilterToConsumerBinding 클래스에서 새 인스턴스를 생성해야 합니다.

아래 코드 스니펫은 이전에 생성한 두 인스턴스(필터 및 소비자)를 해시 테이블로 사용하여 새 인스턴스를 생성하는 데 필요한 속성을 정의합니다. 그런 다음 이를 바인딩을 생성하기 위해 New-CimInstance로 전달합니다.

$CIMBindingProperties=@{
	Filter = [Ref]$CIMFilterInstance
	Consumer = [Ref]$CIMEventConsumer
}

$CIMBinding = New-CimInstance -ClassName __FilterToConsumerBinding -Namespace "root/subscription" -Property $CIMBindingProperties

항상 바인딩이 생성되었는지 확인하려면 다시 Get-CimInstance를 실행하십시오.

Get-CimInstance -Namespace Root/Subscription -ClassName __FilterToConsumerBinding

바인딩에는 FilterConsumer에 대한 정보가 있습니다.

Binding Details

구독 테스트

드디어 완료되었습니다! 이제 수고의 결과물을 테스트할 때입니다! 지금 해야 할 일은 BITS 서비스 상태를 변경하여 PowerShell이 로그 파일에 항목을 작성하는지 확인하는 것뿐입니다. C:\MyCIMMonitoring.txt.

BITS 서비스 상태에 따라 해당 서비스를 중지하거나 시작하거나 Restart-Service cmdlet로 다시 시작하십시오.

Get-Service -Name BITS | Restart-Service

잠시 기다려서 C:\MyCIMMonitoring.txt를 확인하십시오. 이제 이벤트 소비자를 생성할 때 정의한 로그 파일에서 Text를 볼 수 있어야합니다.

Get-Content -Path C:\MyCIMMonitoring.txt
Service Changes are detected

모든 WMI 이벤트 활동을 모니터링하려면 경로 응용 프로그램 및 서비스 로그\Microsoft\Windows\WMI-Activity\Operational의 Windows 이벤트 로그를 확인하십시오.

구독 중지 및 정리

구독이 끝나면 정리할 시간입니다. WMI 이벤트 구독을 중지하고 제거하려면 이벤트 필터, 소비자 및 바인딩 인스턴스를 제거해야합니다.

먼저 Get-CimInstance를 사용하여 이벤트 필터를 제거합니다.

Get-CimInstance -Namespace Root/Subscription -ClassName __EventFilter | Remove-CimInstance

## 여러 인스턴스에 대해
Get-CimInstance -Namespace Root/Subscription -ClassName __EventFilter | where {$.name -like "MyServiceFilter"} | Remove-CimInstance
Registered EventFilter

다음으로, 동일한 방법으로 소비자를 제거합니다.

Get-CimInstance -Namespace Root/Subscription -ClassName LogFileEventConsumer | Remove-CimInstance

## 여러 인스턴스에 대해
Get-CimInstance -Namespace Root/Subscription -ClassName LogFileEventConsumer | where {$_.Name -like "MyServiceConsumer"} | Remove-CimInstance
Getting Consumer from the LogFileEventConsumer Class

마지막으로 바인딩을 제거합니다. 바인딩을 찾는 데 사용되는 속성은 약간 다릅니다. 이름 속성 대신 바인딩 인스턴스에는 실제로 이름 속성이 있는 객체인 필터 속성이 있습니다.

Get-CimInstance -Namespace Root/Subscription -ClassName __FilterToConsumerBinding | Where-Object {$_.Filter.Name -like "MyServiceFilter"} | Remove-CimInstance
Getting the Binding information.

결론

WMI/CIM은 Windows에 대한 정보를 찾고 WMI 이벤트를 사용하여 모니터링하는 편리하고 강력한 시스템입니다. WMI 이벤트를 사용하여 변경 사항을 모니터링하면 컴퓨터 문제에 신속하게 대응할 수 있으므로 각 이벤트에 대한 응답을 자동화하기가 더 쉬워집니다.

WMI 이벤트로 Active Directory 변경 내용을 추적하는 방법를 확인하려면 훌륭한 실제 사례를 참조하세요.

Source:
https://adamtheautomator.com/your-goto-guide-for-working-with-windows-wmi-events-and-powershell/