WMI
윈도우 운영체제에 기본적으로 지원하는 파워쉘(PowerShell)은 WMI, COM, .NET Framework 등 다양한 표준을 지원한다.
다양한 표준 중 WMI(Windows Management Instrumentation)는 윈도우의 리소스에 접근하여 여러가지 설정을 구성할 수 있고, 다양한 부분을 관리할 수 있다.
○ 윈도우의 모든 리소스를 스크립트 형식으로 시스템을 관리
○ Win32 API 보다 진화한 기능으로 윈도우를 이용하는 시스템을 로컬 및 원격으로 관리 (DCOM)
○ namepsace provider 하위에서 동작 (기본적으로 root\cimv2에서 시작)
○ DMTF(분산관리 동적객체)로 표준화 된 WBEM(Web Based Entrprised Management), CIM(Common Information Management)으로 구현
○ WMIC(Windows Management Instrumentation Command-line) 커맨드 라인 인터페이스를 제공
○ wmic, powershell, wbemtest 등 도구를 이용해 WMI를 사용할 수 있으며, WBEM, System.Management.class 등 코딩으로 WMI를 사용
WMI 구조
WMI 구조를 보면 사용자가 WMI 클라이언트 도구를 이용해 쿼리(Query Languages)로 특정한 정보를 조회하고 싶다고 WMI service에게 질의를 한다.
WMI/CIM repository가 질의를 받고 자신의 데이터베이스 내의 정보를 검색한 결과를 WMI service > Query Language > Client 역순서로 전달한다.
WMI namespace
CIM(Common Information Model)은 객체간의 관계로 표현되는 표준을 정의하는 것으로 WMI는 표준을 사용해 CIM 저장소에 모든 객체를 저장하고 관리한다. namespace provider로 구성되어 있으며 최상위에 root\cimv2가 존재한다.
namespace
○ root\cimv2 : 기본이 되는 네임스페이스 다양한 정보
○ root\RSOP : 윈도우 정책 정보
○ root\SecurityCenter2 : 윈도우 백신 및 방화벽 정보
○ root\WMI : WMI 정보
○ root\Policy : 정책 정보
○ ...
class
○ Win32_OperatingSystem : 설치된 운영체제 정보
○ Win32_OptionalFeature : 부가 설치 옵션 정보
○ Win32_PnPDevice : 설치된 디바이스 정보
○ Win32_PNPSignedDriver : 설치된 디바이스 드라이버 정보
○ Win32_Service : 시스템 서비스 정보
○ ...
WMI 테스트
WMI 데이터에 접근하는 방법은 여러가지가 있지만 대부분 WMI 쿼리를 사용한다. 간단하게 테스트를 해볼 수 있는 도구는 윈도우에 기본적으로 설치되어 있는 wbemtest.exe이다.
WMI 실습
시스템에 존재하는 드라이브 정보, 프로세스 정보를 파워쉘에서 지원하는 WMI 쿼리를 통해 확인하는 방법을 알아본다.
Get-WmiObject를 이용해 기본 드라이브 정보를 확인한다. 드라이브 정보를 확인할 수 있는 클래스는 win32_logicaldisk인데, 기본 드라이브 정보를 확인하기 위해 drivetype을 3으로 설정한다.
PS D:\tmp_download> Get-WmiObject -Query "select * from win32_logicaldisk where drivetype=3"
DeviceID : C:
DriveType : 3
ProviderName :
FreeSpace : 55527411712
Size : 256058060800
VolumeName :
DeviceID : D:
DriveType : 3
ProviderName :
FreeSpace : 264562941952
Size : 989467766784
VolumeName :
root\cimv2 네임스페이스에 존재하는 모든 클래스 목록 중 프로세스와 관련된 클래스 정보를 출력한다.
PS D:\tmp_download> get-wmiobject -namespace 'root/cimv2' -list | ?{$_.name -match "process"}
NameSpace: ROOT\cimv2
Name Methods Properties
---- ------- ----------
Win32_ProcessTrace {} {ParentProcessID, ProcessID, ProcessName, SECURITY_DESCRIPT...
Win32_ProcessStartTrace {} {ParentProcessID, ProcessID, ProcessName, SECURITY_DESCRIPT...
Win32_ProcessStopTrace {} {ExitStatus, ParentProcessID, ProcessID, ProcessName...}
CIM_Processor {SetPowerState, R... {AddressWidth, Availability, Caption, ConfigManagerErrorCod...
Win32_Processor {SetPowerState, R... {AddressWidth, Architecture, Availability, Caption...}
CIM_Process {} {Caption, CreationClassName, CreationDate, CSCreationClassN...
Win32_Process {Create, Terminat... {Caption, CommandLine, CreationClassName, CreationDate...}
Win32_NamedJobObjectProcess {} {Collection, Member}
select -expandproperty methods를 지정하면 win32_process 클래스에 존재하는 모든 메소드 정보가 출력된다.
PS D:\tmp_download> get-wmiobject -class win32_process -list | select -expandproperty methods
Name : Create
InParameters : System.Management.ManagementBaseObject
OutParameters : System.Management.ManagementBaseObject
Origin : Win32_Process
Qualifiers : {Constructor, Implemented, MappingStrings, Privileges...}
Name : Terminate
InParameters : System.Management.ManagementBaseObject
OutParameters : System.Management.ManagementBaseObject
Origin : Win32_Process
Qualifiers : {Destructor, Implemented, MappingStrings, Privileges...}
win32_process 클래스에 존재하는 메소드 중 create() 메소드를 실행하려면 -argumentlist를 지정하면 된다.
PS D:\tmp_download> invoke-wmimethod -class win32_process -name create -argumentlist "notepad.exe"
__GENUS : 2
__CLASS : __PARAMETERS
__SUPERCLASS :
__DYNASTY : __PARAMETERS
__RELPATH :
__PROPERTY_COUNT : 2
__DERIVATION : {}
__SERVER :
__NAMESPACE :
__PATH :
ProcessId : 4360
ReturnValue : 0
USB를 컴퓨터에 연결하거나 해제할 때 계산기가 실행되게 하려면 볼륨 관련 이벤트를 등록해야 한다.
코드를 보면 $query 변수는 5초 간격으로 볼륨 정보가 변경되었는지 확인하는 역할이고, $action 변수는 5초 간격으로 모니터링하다가 USB가 연결 및 해제되면 계산기를 실행하는 역할이다.
resigter-wmievent는 일회성 이벤트를 등록할 때 사용한다.
PS D:\> $query = "select * from win32_volumechangeevent within 5"
PS D:\> $action = {invoke-wmimethod win32_process -name create -argumentlist 'calc.exe'}
PS D:\> register-wmievent -query $query -sourceidentifier 'usbevent' -action $action
Id Name State HasMoreData Location Command
-- ---- ----- ----------- -------- -------
1 usbevent NotStarted False invoke-wmimethod win32...
일회성 이벤트가 등록되면 5초 간격으로 볼륨 정보를 모니터링하기 시작한다. 실제로 컴퓨터에 USB를 연결하면 이벤트가 발생하여 계산기가 실행된다.
하지만, 일회성 이벤트이므로 시스템을 재부팅하면 이벤트가 동작하지 않는다. 이를 해결하려면 영구적으로 동작하는 이벤트로 등록을 해야 한다.