PowerShell WMI: Windows 작업 자동화

윈도우 관리 인터페이스 (WMI)는 오랜 기간 동안 윈도우에서 사용되어 왔습니다. 많은 IT 전문가들은 WMI를 직접 사용하거나 WMI에서 정보를 읽는 도구를 사용해 왔습니다. PowerShell WMI cmdlet이 내장되어 있다는 사실을 알고 계셨나요?

WMI는 Windows 기기에 대한 정보를 수집하고 Windows 내의 다양한 서비스를 조작하기 위한 사실상의 위치입니다. WMI의 다양한 정보를 활용할 수 있도록 PowerShell WMI를 사용할 수 있습니다. PowerShell을 사용하여 WMI를 조사하면 Windows 컴퓨터에서 수천 가지 작업을 자동화할 수 있습니다.

다행히도 PowerShell에서 처음으로 WMI에 대한 명령을 제공한 시스템 중 하나가 있습니다. 기본 PowerShell WMI cmdlet을 사용할 수 있으므로 IT 관리자는 PowerShell의 쉽게 이해할 수 있는 동사/명사 구문을 활용하여 WMI와 상호 작용할 수 있습니다. 또한, 전문 사용자는 표준 PowerShell 명령만 사용하여 WMI 이벤트와 클래스를 직접 호출할 수도 있습니다.

PowerShell WMI Cmdlets vs CIM

PowerShell에서 WMI를 사용할 때 “세트”라고 하는 두 가지 명령이 있습니다. 일부 사람들은 이러한 “세트”를 WMI와 CIM cmdlet의 “옛날” 방식으로 참조합니다. WMI에서 정보를 조회할 때 두 방식은 동일한 정보를 반환하지만 약간 다른 방식으로 접근합니다. WMI에서 정보를 읽는 “옛날” 방식은 Get-WmiObject 명령을 사용하는 것입니다. 다른 WMI cmdlet에는 Invoke-WmiMethod, Register-WMIEvent 등이 포함되어 있지만 이 글에서는 다루지 않을 것입니다.

PowerShell WMI cmdlet Get-WmiObject은 작동하지만 심각한 단점이 있습니다. 원격 컴퓨터를 쿼리할 때 DCOM에 의존하며 DCOM은 역사적으로 나쁜 사람들의 공격 벡터로 알려져 있습니다. DCOM은 일반적으로 다양한 방화벽에 의해 차단됩니다. 이것은 “옛날” 방법이기 때문에 이 방법에 대해서는 다루지 않겠습니다. 대신에, 우리는 CIM cmdlet 중심인 Get-CimInstance에 초점을 맞출 것입니다.

DCOM Component Services

Get-WmiObjectGet-CimInstance의 큰 차이점은 원격 컴퓨터에 액세스하기 위해 DCOM 대신 Get-CimInstance가 익숙한 PowerShell 리모팅 기능의 전송으로 사용하는 WSMAN 프로토콜을 사용한다는 것입니다.

PowerShell CIM Cmdlets

원격 컴퓨터의 Windows 버전에 대한 정보를 반환하고 싶다고 가정해 봅시다. 이 경우 DC라는 컴퓨터에서 정보를 확인하고 싶습니다. 정보를 포함하는 WMI 클래스와 쿼리하려는 컴퓨터 이름을 지정하여 이 작업을 수행할 수 있습니다.

아래에서 볼 수 있듯이 Get-CimInstance는 기본적으로 클래스 내의 모든 속성을 표시하지 않기 때문에 출력을 Select-Object 명령으로 파이핑하여 모든 속성을 반환해야 했습니다.

PS> Get-CimInstance -ClassName Win32_OperatingSystem -ComputerName DC | Select *
Status                                    : OK
Name                                      : Microsoft Windows 10 Pro|C:\WINDOWS|\Device\Harddisk0\Partition2
FreePhysicalMemory                        : 1802336
FreeSpaceInPagingFiles                    : 800308
FreeVirtualMemory                         : 1472916
Caption                                   : Microsoft Windows 2016
Description                               :
InstallDate                               : 7/5/2018 6:04:09 PM
CreationClassName                         : Win32_OperatingSystem
CSCreationClassName                       : Win32_ComputerSystem
--snip-

속성을 통해 정보를 수집하는 것뿐만 아니라 클래스에서도 WMI/CIM 메서드를 호출할 수 있습니다. 이에 대한 좋은 예로 원격 컴퓨터에서 프로세스를 중지하는 것이 있습니다. 기본적으로 PowerShell의 Stop-Process 명령을 통해 이 작업을 수행할 수는 없습니다. 그러나 WMI 쿼리를 통해 가능합니다. 원격 프로세스를 종료하기 위해서는 먼저 종료할 프로세스를 확인해야 합니다. 원격 컴퓨터에서 실행 중인 모든 프로세스를 Win32_Process 클래스를 통해 열거할 수 있습니다.

PS> Get-CimInstance -ClassName CIM_Process -ComputerName DC

ProcessId Name                                      HandleCount WorkingSetSize VirtualSize   PSComputerName
--------- ----                                      ----------- -------------- -----------   --------------
0         System Idle Process                       0           4096           65536         DC
4         System                                    631         212992         3465216       DC
232       smss.exe                                  52          823296         4325376       DC
328       csrss.exe                                 258   om      3346432        49483776      DC
392       csrss.exe                                 87          2789376        44507136      DC
400       wininit.exe                               80          3072000        2199065096192 DC
428       winlogon.exe                              119         4431872        2199079510016 DC

종료할 프로세스를 확인한 후에는 해당 프로세스의 이름을 Win32_Process 클래스의 Terminate() 메서드에 전달할 수 있습니다. 이를 위해 종료할 프로세스의 인스턴스를 캡처해야 합니다.

아래에서는 Filter 매개변수를 사용하여 ccmexec.exe 프로세스만 받도록 설정했습니다. 이는 중요합니다!

인스턴스를 캡처한 후에는 아래와 같이 Invoke-CimMethod 명령을 사용하여 프로세스를 종료하는 Terminate() 메서드를 호출할 수 있습니다.

PS> $instance = Get-CimInstance -ClassName CIM_Process -ComputerName DC -Filter 'Name = "ccmexec.exe"'
PS> $instance

ProcessId Name        HandleCount WorkingSetSize VirtualSize PSComputerName
--------- ----        ----------- -------------- ----------- --------------
3528      CcmExec.exe 878         34246656       158261248   DC


PS> Invoke-CimMethod -InputObject $instance -MethodName Terminate

ReturnValue PSComputerName
----------- --------------
          0 DC

요약

더 자세한 내용은 PowerShell에서 WMI를 사용하는 방법 및 특히 여기에서 다루지 않은 PowerShell WMI cmdlet Get-WmiObject 사용에 대해 알고 싶다면 Get-WmiObject: 로컬 및 원격 컴퓨터에서 WMI 쿼리를 확인해 보시기 바랍니다.

CIM cmdlets 및 PowerShell에서 작동하는 방법에 대한 전체 세부 정보를 얻으려면 Technet의 CIM Cmdlets 소개 기사를 참조하십시오. 거기에서 여러 CIM cmdlets 및 해당 스크립트에서 사용될 수 있는 방법을 모두 볼 수 있습니다.

Source:
https://adamtheautomator.com/powershell-wmi/