7장 - WMI 작업

WMI 및 CIM

Windows PowerShell은 WMI(Windows Management Instrumentation)와 같은 다른 기술을 사용하기 위한 cmdlet과 함께 기본적으로 제공됩니다. WMI cmdlet은 더 이상 사용되지 않으며 PowerShell 6 이상에서는 사용할 수 없지만 Windows PowerShell에서 실행되는 이전 스크립트에서 발생할 수 있으므로 여기서 설명합니다. 새 개발의 경우 대신 CIM cmdlet을 사용합니다.

추가 소프트웨어 또는 모듈을 설치하지 않고도 PowerShell에 있는 몇 가지 네이티브 WMI cmdlet이 있습니다. Get-Command 을 사용하여 Windows PowerShell에 존재하는 WMI cmdlet을 확인할 수 있습니다. 다음은 PowerShell 버전 5.1을 실행하는 필자의 Windows 10 랩 환경 컴퓨터에서 얻은 결과입니다. 실행 중인 PowerShell 버전에 따라 결과가 다를 수 있습니다.

Get-Command -Noun WMI*
CommandType     Name                                               Version    Source
-----------     ----                                               -------    ------
Cmdlet          Get-WmiObject                                      3.1.0.0    Microsof...
Cmdlet          Invoke-WmiMethod                                   3.1.0.0    Microsof...
Cmdlet          Register-WmiEvent                                  3.1.0.0    Microsof...
Cmdlet          Remove-WmiObject                                   3.1.0.0    Microsof...
Cmdlet          Set-WmiInstance                                    3.1.0.0    Microsof...

CIM(일반 정보 모델) cmdlet은 PowerShell 버전 3.0에서 도입되었습니다. CIM cmdlet은 Windows 및 비 Windows 컴퓨터에서 모두 사용할 수 있도록 설계되었습니다.

CIM cmdlet은 모두 모듈 내에 포함됩니다. CIM cmdlet 목록을 얻고 싶다면 아래 예제에서처럼 Get-CommandModule 매개 변수와 함께 사용해야 합니다.

Get-Command -Module CimCmdlets
CommandType     Name                                               Version    Source
-----------     ----                                               -------    ------
Cmdlet          Export-BinaryMiLog                                 1.0.0.0    CimCmdlets
Cmdlet          Get-CimAssociatedInstance                          1.0.0.0    CimCmdlets
Cmdlet          Get-CimClass                                       1.0.0.0    CimCmdlets
Cmdlet          Get-CimInstance                                    1.0.0.0    CimCmdlets
Cmdlet          Get-CimSession                                     1.0.0.0    CimCmdlets
Cmdlet          Import-BinaryMiLog                                 1.0.0.0    CimCmdlets
Cmdlet          Invoke-CimMethod                                   1.0.0.0    CimCmdlets
Cmdlet          New-CimInstance                                    1.0.0.0    CimCmdlets
Cmdlet          New-CimSession                                     1.0.0.0    CimCmdlets
Cmdlet          New-CimSessionOption                               1.0.0.0    CimCmdlets
Cmdlet          Register-CimIndicationEvent                        1.0.0.0    CimCmdlets
Cmdlet          Remove-CimInstance                                 1.0.0.0    CimCmdlets
Cmdlet          Remove-CimSession                                  1.0.0.0    CimCmdlets
Cmdlet          Set-CimInstance                                    1.0.0.0    CimCmdlets

CIM cmdlet은 여전히 WMI로 작업할 수 있도록 허용하므로 누군가가 "PowerShell CIM cmdlet을 사용하여 WMI를 쿼리할 때..."라는 문을 만들 때 혼동하지 마세요.

이전에 멘션 WMI는 PowerShell과는 별개의 기술이며, WMI에 액세스하기 위해 CIM cmdlet을 사용하고 있습니다. 다음 예제와 같이 WQL(WMI 쿼리 언어)을 사용하여 WMI를 쿼리하는 이전 VBScript를 찾을 수 있습니다.

strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
    & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")

Set colBIOS = objWMIService.ExecQuery _
    ("Select * from Win32_BIOS")

For each objBIOS in colBIOS
    Wscript.Echo "Manufacturer: " & objBIOS.Manufacturer
    Wscript.Echo "Name: " & objBIOS.Name
    Wscript.Echo "Serial Number: " & objBIOS.SerialNumber
    Wscript.Echo "SMBIOS Version: " & objBIOS.SMBIOSBIOSVersion
    Wscript.Echo "Version: " & objBIOS.Version
Next

이러한 VBScript에서 WQL 쿼리를 가져온 다음 수정 없이 Get-CimInstance cmdlet과 함께 사용할 수 있습니다.

Get-CimInstance -Query 'Select * from Win32_BIOS'
SMBIOSBIOSVersion : 090006
Manufacturer      : American Megatrends Inc.
Name              : Intel(R) Xeon(R) CPU E3-1505M v5 @ 2.80GHz
SerialNumber      : 3810-1995-1654-4615-2295-2755-89
Version           : VRTUAL - 4001628

일반적으로 PowerShell을 사용하여 WMI를 쿼리하는 방법은 아닙니다. 그러나 작동하며 기존 VBScript를 PowerShell로 쉽게 마이그레이션할 수 있습니다. WMI를 쿼리하는 한 라이너 작성을 시작할 때 다음 구문을 사용합니다.

Get-CimInstance -ClassName Win32_BIOS
SMBIOSBIOSVersion : 090006
Manufacturer      : American Megatrends Inc.
Name              : Intel(R) Xeon(R) CPU E3-1505M v5 @ 2.80GHz
SerialNumber      : 3810-1995-1654-4615-2295-2755-89
Version           : VRTUAL - 4001628

일련 번호만 원하는 경우 출력을 파이프하고 Select-Object SerialNumber 속성만 지정할 수 있습니다.

Get-CimInstance -ClassName Win32_BIOS | Select-Object -Property SerialNumber
SerialNumber
------------
3810-1995-1654-4615-2295-2755-89

기본적으로 사용되지 않는 백그라운드에서 검색되는 몇 가지 속성이 있습니다. 로컬 컴퓨터에서 WMI를 쿼리할 때는 별로 중요하지 않을 수 있습니다. 그러나 원격 컴퓨터 쿼리를 시작하면 해당 정보를 반환하는 추가 처리 시간뿐만 아니라 네트워크를 통해 가져와야 하는 불필요한 추가 정보도 있습니다. Get-CimInstance 에는 검색되는 정보를 제한하는 속성 매개 변수가 있습니다. 이렇게 하면 WMI에 대한 쿼리의 효율성이 높아집니다.

Get-CimInstance -ClassName Win32_BIOS -Property SerialNumber |
Select-Object -Property SerialNumber
SerialNumber
------------
3810-1995-1654-4615-2295-2755-89

이전 결과는 개체를 반환했습니다. 간단한 문자열을 반환하려면 ExpandProperty 매개 변수를 사용합니다.

Get-CimInstance -ClassName Win32_BIOS -Property SerialNumber |
Select-Object -ExpandProperty SerialNumber
3810-1995-1654-4615-2295-2755-89

또한 구문의 점선 스타일을 사용하여 간단한 문자열을 반환할 수도 있습니다. 이렇게 하면 .에 파이프 Select-Object할 필요가 없습니다.

(Get-CimInstance -ClassName Win32_BIOS -Property SerialNumber).SerialNumber
3810-1995-1654-4615-2295-2755-89

CIM cmdlet을 사용하여 원격 컴퓨터 쿼리

여전히 PowerShell을 할 일기본 사용자인 로컬 관리자로 실행하고 있습니다. cmdlet을 사용하여 Get-CimInstance 원격 컴퓨터에서 정보를 쿼리하려고 하면 액세스 거부 오류 메시지가 표시됩니다.

Get-CimInstance -ComputerName dc01 -ClassName Win32_BIOS
Get-CimInstance : Access is denied.
At line:1 char:1
+ Get-CimInstance -ComputerName dc01 -ClassName Win32_BIOS
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : PermissionDenied: (root\cimv2:Win32_BIOS:String) [Get-CimI
   nstance], CimException
    + FullyQualifiedErrorId : HRESULT 0x80070005,Microsoft.Management.Infrastructure.Cim
   Cmdlets.GetCimInstanceCommand
    + PSComputerName        : dc01

많은 사람들이 PowerShell을 사용할 때 보안을 걱정하지만 PowerShell에서는 GUI와 완전히 같은 권한을 사용할 수 있습니다. 똑같아야 합니다. 이전 예제에는 PowerShell을 실행하는 사용자에게 DC01 서버에서 WMI 정보를 쿼리할 수 있는 권한이 없다는 문제가 있습니다. Get-CimInstance에는 Credential 매개 변수가 없기 때문에 도메인 관리자로 PowerShell을 다시 시작할 수 있습니다. 하지만, 날 믿어, 그건 좋은 생각이 아니다 때문에 다음 PowerShell에서 실행 하는 아무것도 할 기본 관리자로 실행 될 것 이다. 상황에 따라 보안 관점에서 위험할 수 있습니다.

필자는 최소 권한 원칙에 따라, 명령에 Credential 매개 변수가 있다면 이 변수를 이용해 각 명령의 권한을 도메인 관리자 계정으로 승격합니다. Get-CimInstance에는 Credential 매개 변수가 없으니 이런 상황에서는 먼저 CimSession을 만들어야 합니다. 그런 다음 컴퓨터 이름 대신 CimSession을 사용하여 원격 컴퓨터에서 WMI를 쿼리합니다.

$CimSession = New-CimSession -ComputerName dc01 -Credential (Get-Credential)
cmdlet Get-Credential at command pipeline position 1
Supply values for the following parameters:
Credential

CIM 세션은 $CimSession이라는 변수에 저장됩니다. 새 세션을 만들기 전에 먼저 실행되도록 cmdlet을 괄호로 지정 Get-Credential 하여 대체 자격 증명을 묻는 메시지를 표시했습니다. 이 챕터의 뒷부분에서 대체 자격 증명을 지정하는 또 다른 효율적인 방법을 보여 주겠지만, 더 복잡하게 만들기 전에 이 기본 개념을 이해하는 것이 중요합니다.

이제 이전 예제에서 만든 CIM 세션을 Get-CimInstance cmdlet과 함께 사용하면 원격 컴퓨터의 WMI에서 BIOS 정보를 쿼리할 수 있습니다.

Get-CimInstance -CimSession $CimSession -ClassName Win32_BIOS
SMBIOSBIOSVersion : 090006
Manufacturer      : American Megatrends Inc.
Name              : Intel(R) Xeon(R) CPU E3-1505M v5 @ 2.80GHz
SerialNumber      : 0986-6980-3916-0512-6608-8243-13
Version           : VRTUAL - 4001628
PSComputerName    : dc01

단순히 컴퓨터 이름을 지정하는 대신 CIM 세션을 사용하면 다양한 추가 이점을 얻을 수 있습니다. 동일한 컴퓨터에 여러 쿼리를 실행하는 경우 CIM 세션을 사용하는 것이 각 쿼리에 컴퓨터 이름을 사용하는 것보다 더 효율적입니다. CIM 세션을 만들 때는 연결이 한 번만 설정됩니다. 그런 다음, 여러 쿼리가 동일한 세션을 사용하여 정보를 검색합니다. 컴퓨터 이름을 사용하려면 cmdlet이 각 개별 쿼리와의 연결을 설정하고 해제해야 합니다.

cmdlet은 Get-CimInstance 기본적으로 WSMan 프로토콜을 사용합니다. 즉, 원격 컴퓨터에 연결하려면 PowerShell 버전 3.0 이상이 필요합니다. 실제로 중요한 PowerShell 버전이 아니라 스택 버전입니다. 스택 버전은 Test-WSMan cmdlet을 사용하여 확인할 수 있습니다. 버전 3.0이어야 합니다. PowerShell 버전 3.0 이상에서 찾을 수 있는 버전입니다.

Test-WSMan -ComputerName dc01
wsmid           : http://schemas.dmtf.org/wbem/wsman/identity/1/wsmanidentity.xsd
ProtocolVersion : http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd
ProductVendor   : Microsoft Corporation
ProductVersion  : OS: 0.0.0 SP: 0.0 Stack: 3.0

이전 WMI cmdlet은 이전 버전의 Windows와 호환되는 DCOM 프로토콜을 사용합니다. 그러나 DCOM은 일반적으로 최신 버전의 Windows에서 방화벽에 의해 차단됩니다. cmdlet New-CimSessionOption 을 사용하면 .에서 사용할 DCOM 프로토콜 연결을 만들 수 있습니다 New-CimSession. 이렇게 하면 Get-CimInstance cmdlet을 사용하여 windows Server 2000 이전 버전의 Windows와 통신할 수 있습니다. 즉, DCOM 프로토콜을 사용하도록 구성된 CimSession과 함께 cmdlet을 사용하는 Get-CimInstance 경우 원격 컴퓨터에서 PowerShell이 필요하지 않습니다.

cmdlet을 사용하여 New-CimSessionOption DCOM 프로토콜 옵션을 만들고 변수에 저장합니다.

$DCOM = New-CimSessionOption -Protocol Dcom

효율성을 위해 do기본 관리자 또는 관리자 자격 증명을 변수에 저장하여 각 명령에 대해 지속적으로 입력할 필요가 없습니다.

$Cred = Get-Credential
cmdlet Get-Credential at command pipeline position 1
Supply values for the following parameters:
Credential

Windows Server 2008(R2가 아닌)을 실행하는 SQL03이라는 서버가 있습니다. PowerShell이 기본적으로 설치되지 않는 최신 Windows Server 운영 체제입니다.

DCOM 프로토콜을 사용하여 SQL03에 대한 CimSession 을 만듭니다.

$CimSession = New-CimSession -ComputerName sql03 -SessionOption $DCOM -Credential $Cred

이전 명령에서 이번에는 수동으로 다시 입력하지 않고 자격 증명 매개 변수의 값으로 명명 $Cred 변수를 지정했습니다.

쿼리의 출력은 사용되는 기본 프로토콜에 관계없이 동일합니다.

Get-CimInstance -CimSession $CimSession -ClassName Win32_BIOS
SMBIOSBIOSVersion : 090006
Manufacturer      : American Megatrends Inc.
Name              : Intel(R) Xeon(R) CPU E3-1505M v5 @ 2.80GHz
SerialNumber      : 7237-7483-8873-8926-7271-5004-86
Version           : VRTUAL - 4001628
PSComputerName    : sql03

Get-CimSession cmdlet은 현재 연결된 CimSessions 및 사용 중인 프로토콜을 확인하는 데 사용됩니다.

Get-CimSession
Id           : 1
Name         : CimSession1
InstanceId   : 80742787-e38e-41b1-a7d7-fa1369cf1402
ComputerName : dc01
Protocol     : WSMAN

Id           : 2
Name         : CimSession2
InstanceId   : 8fcabd81-43cf-4682-bd53-ccce1e24aecb
ComputerName : sql03
Protocol     : DCOM

이전에 만든 CimSessions 를 모두 검색하여 이름이 지정된 $CimSession변수에 저장합니다.

$CimSession = Get-CimSession

하나는 WSMan 프로토콜을 사용하는 명령으로, 다른 하나는 DCOM을 사용하는 명령으로 두 컴퓨터를 모두 쿼리합니다.

Get-CimInstance -CimSession $CimSession -ClassName Win32_BIOS
SMBIOSBIOSVersion : 090006
Manufacturer      : American Megatrends Inc.
Name              : Intel(R) Xeon(R) CPU E3-1505M v5 @ 2.80GHz
SerialNumber      : 0986-6980-3916-0512-6608-8243-13
Version           : VRTUAL - 4001628
PSComputerName    : dc01

SMBIOSBIOSVersion : 090006
Manufacturer      : American Megatrends Inc.
Name              : Intel(R) Xeon(R) CPU E3-1505M v5 @ 2.80GHz
SerialNumber      : 7237-7483-8873-8926-7271-5004-86
Version           : VRTUAL - 4001628
PSComputerName    : sql03

WMI 및 CIM cmdlet에 대한 수많은 블로그 문서를 작성했습니다. 가장 유용한 기능 중 하나는 WSMan 또는 DCOM을 사용할지 자동으로 결정하고 수동으로 어떤 세션을 파악하지 않고도 CIM 세션을 자동으로 설정하도록 만든 함수에 관한 것입니다. 이 블로그 문서의 제목 은 Dcom으로 대체하여 원격 컴퓨터에 CimSessions를 만드는 PowerShell 함수입니다.

CIM 세션을 완료하면 cmdlet을 사용하여 Remove-CimSession 제거해야 합니다. 모든 CIM 세션을 제거하려면 .에 파이프 Get-CimSession 하기만 하면 됩니다 Remove-CimSession.

Get-CimSession | Remove-CimSession

요약

이 챕터에서는 PowerShell을 사용하여 로컬 컴퓨터와 원격 컴퓨터 모두에서 WMI를 사용하는 방법을 알아보았습니다. 또한 CIM cmdlet을 사용하여 WSMan이나 DCOM 프로토콜을 사용하는 원격 컴퓨터에서 작업하는 방법도 알아보았습니다.

검토

  1. WMI 및 CIM cmdlet의 차이점은 무엇인가요?
  2. 기본적으로 Get-CimInstance cmdlet에서는 어떤 프로토콜을 사용하나요?
  3. 컴퓨터 이름을 Get-CimInstance지정하는 대신 CIM 세션을 사용할 경우의 이점은 무엇인가요?
  4. Get-CimInstance에 사용할 프로토콜을 기본 프로토콜이 아닌 다른 프로토콜로 지정하려면 어떻게 해야 하나요?
  5. CIM 세션을 닫거나 제거하려면 어떻게 해야 하나요?