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 11 시스템에서 제공됩니다. 실행 중인 PowerShell 버전에 따라 결과가 다를 수 있습니다.
Get-Command -Noun WMI*
CommandType Name Version
----------- ---- -------
Cmdlet Get-WmiObject 3.1.0.0
Cmdlet Invoke-WmiMethod 3.1.0.0
Cmdlet Register-WmiEvent 3.1.0.0
Cmdlet Remove-WmiObject 3.1.0.0
Cmdlet Set-WmiInstance 3.1.0.0
CIM(일반 정보 모델) cmdlet은 PowerShell 3.0에서 도입되었으며 전용 모듈 내에서 그룹화됩니다. 사용 가능한 모든 CIM cmdlet을 나열하려면 다음 예제와 같이 Get-Command
매개 변수와 함께 cmdlet을 사용합니다.
Get-Command -Module CimCmdlets
CommandType Name Version
----------- ---- -------
Cmdlet Export-BinaryMiLog 1.0.0.0
Cmdlet Get-CimAssociatedInstance 1.0.0.0
Cmdlet Get-CimClass 1.0.0.0
Cmdlet Get-CimInstance 1.0.0.0
Cmdlet Get-CimSession 1.0.0.0
Cmdlet Import-BinaryMiLog 1.0.0.0
Cmdlet Invoke-CimMethod 1.0.0.0
Cmdlet New-CimInstance 1.0.0.0
Cmdlet New-CimSession 1.0.0.0
Cmdlet New-CimSessionOption 1.0.0.0
Cmdlet Register-CimIndicationEvent 1.0.0.0
Cmdlet Remove-CimInstance 1.0.0.0
Cmdlet Remove-CimSession 1.0.0.0
Cmdlet Set-CimInstance 1.0.0.0
CIM cmdlet을 사용하면 여전히 WMI를 사용할 수 있으므로 다른 사용자가 "PowerShell CIM cmdlet으로 WMI를 쿼리할 때"라고 말하면 혼동하지 마세요.
앞에서 설명한 것처럼 WMI는 PowerShell과는 별개의 기술이며, CIM cmdlet을 사용하여 WMI에 액세스하기만 하면 됩니다. 다음 예제와 같이 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 쿼리를 가져와 수정 없이 cmdlet과 함께 Get-CimInstance
사용할 수 있습니다.
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를 쿼리하는 방법이 아닙니다. 그러나 작동하며 기존 Visual Basic 스크립트를 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를 쿼리할 때 사용되지 않는 여러 속성이 백그라운드에서 검색됩니다. 로컬 컴퓨터에서 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:Stri
ng) [Get-CimInstance], CimException
+ FullyQualifiedErrorId : HRESULT 0x80070005,Microsoft.Management.Infra
structure.CimCmdlets.GetCimInstanceCommand
+ PSComputerName : dc01
많은 사람들이 PowerShell과 관련된 보안 문제를 가지고 있지만 PowerShell의 사용 권한은 GUI와 동일합니다. 정확히 그것입니다. 이전 예제의 문제는 PowerShell을 실행하는 사용자에게 DC01 서버의 WMI 정보를 쿼리할 권한이 없다는 것입니다.
Get-CimInstance
매개 변수가 없으므로 PowerShell을 도메인 관리자 로 다시 실행할 수 있습니다. 그러나 PowerShell에서 실행하는 모든 항목이 도메인 관리자로 실행되므로 좋지 않습니다. 상황에 따라 이 시나리오는 보안 관점에서 위험할 수 있습니다.
최소 권한 원칙을 사용하여 명령에 자격 증명 매개 변수가 있는 경우 명령별로 도메인 관리자 계정으로 승격합니다.
Get-CimInstance
에는 자격 증명 매개 변수가 없으므로 이 시나리오의 솔루션은 먼저 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
변수에 저장되었습니다. 괄호 안에 Get-Credential
cmdlet을 지정하여 먼저 실행되도록 하고, 새 세션을 만들기 전에 대체 자격 증명을 묻는 메시지를 표시합니다. 이 장 뒷부분에서 대체 자격 증명을 지정하는 또 다른 효율적인 방법을 보여 주지만, 더 복잡하게 만들기 전에 이 기본 개념을 이해하는 것이 중요합니다.
이제 Get-CimInstance
cmdlet과 함께 이전 예제에서 만든 CIM 세션을 사용하여 원격 컴퓨터의 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 버전이 아니라 스택 버전입니다. 스택 버전은 cmdlet을 Test-WSMan
사용하여 확인할 수 있습니다.
PowerShell 버전 3.0 이상에서 찾을 수 있는 버전 3.0이어야 합니다.
Test-WSMan -ComputerName dc01
wsmid : http://schemas.dmtf.org/wbem/wsman/identity/1/wsmanidentit
y.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 프로토콜을 사용합니다.
그러나 방화벽은 일반적으로 최신 버전의 Windows에서 DCOM을 차단합니다.
New-CimSessionOption
cmdlet을 사용하면 New-CimSession
에서 사용할 DCOM 프로토콜 연결을 만들 수 있습니다. 이 옵션을 사용하면 cmdlet이 Get-CimInstance
Windows Server 2000 이전 버전의 Windows와 통신할 수 있습니다. 또한 이 기능은 DCOM 프로토콜을 사용하도록 구성된 CimSession과 함께 cmdlet을 사용할 Get-CimInstance
때 원격 컴퓨터에서 PowerShell이 필요하지 않음을 의미합니다.
cmdlet을 사용하여 New-CimSessionOption
DCOM 프로토콜 옵션을 만들고 변수에 저장합니다.
$DCOM = New-CimSessionOption -Protocol Dcom
효율성을 위해 각 명령에 대해 지속적으로 입력할 필요가 없도록 도메인 관리자 또는 관리자 자격 증명을 변수에 저장할 수 있습니다.
$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 세션을 설정하는 PowerShell 함수를 제공합니다. 자세한 내용은 Dcom으로 대체하여 원격 컴퓨터에 CimSessions를 만드는 PowerShell 함수를 참조하세요.
CIM 세션을 마치면 Remove-CimSession
cmdlet을 사용하여 제거합니다. 모든 CIM 세션을 제거하려면 Get-CimSession
을(를) Remove-CimSession
으로 연결 및 전달하세요.
Get-CimSession | Remove-CimSession
요약
이 장에서는 PowerShell을 사용하여 로컬 및 원격 컴퓨터에서 WMI를 사용하는 방법을 알아보았습니다. 또한 CIM cmdlet을 사용하여 WSMan 및 DCOM 프로토콜을 사용하여 원격 컴퓨터로 작업하는 방법도 알아보았습니다.
검토
- WMI 및 CIM cmdlet의 차이점은 무엇인가요?
- 기본적으로 cmdlet은 어떤 프로토콜을
Get-CimInstance
사용하나요? - 컴퓨터 이름을 지정하는 대신 CIM 세션을 사용하면 어떤 이점이 있나요
Get-CimInstance
? - 기본 프로토콜이 아닌 다른 프로토콜을
Get-CimInstance
에 사용하려면 어떻게 지정해야 하나요? - CIM 세션을 닫거나 제거하려면 어떻게 해야 합니까?
참고문헌
PowerShell