컴퓨터의 CPU나 메모리 사양, 시리얼 번호나 모델명, 설치된 소프트웨어 버전을 확인하고 싶은데 어디서 찾아야 할지 몰랐던 적이 있으신가요? 사실 엑셀에 간단한 코드 몇 줄만 추가하면 Windows PC의 방대한 정보를 한꺼번에 추출할 수 있습니다.
믿기 어려워 보이지만, 사용법만 안다면 Windows는 그만큼 강력한 운영체제입니다.
약간의 코딩 작업이 필요하지만 걱정하지 마세요. 이 글에서는 필요한 코드 전부와 이를 엑셀에 적용해 실행하는 방법까지 모두 안내합니다. 작업이 끝나면 파일을 열 때마다 컴퓨터 시스템에 관한 거의 모든 정보를 알려주는 엑셀 시트를 갖게 될 것입니다.
참고로 이 기능은 데스크톱 버전 엑셀에서만 동작하며, Office 무료 체험판을 통해서도 사용할 수 있습니다.
WMI의 마법
Microsoft 운영체제가 설치된 모든 컴퓨터에는 WMI(Windows Management Instrumentation)라는 강력한 확장 도구 세트가 내장되어 있습니다. WMI를 활용하면 컴퓨터 하드웨어, 운영체제, 설치된 소프트웨어에 관한 정보와 사양을 매우 폭넓게 조회할 수 있습니다.
더욱 좋은 점은 WMI가 거의 모든 Microsoft Office 제품에서 사용할 수 있는 VBA 같은 프로그래밍 언어로 접근 가능하다는 것입니다.
자동화 스프레드시트 설정하기
먼저 새 엑셀 통합 문서를 만들고 MyComputerInfo.xlsm(매크로 사용 가능 형식)처럼 이름을 지정하세요. 파일을 연 다음 Sheet1은 건너뛰고, 나머지 11개의 시트를 아래 이름대로 변경합니다(코드에서 해당 이름을 참조하므로 반드시 영문 그대로 입력해야 합니다):
- Network (네트워크)
- LogicalDisk (논리 디스크)
- Processor (프로세서)
- Physical Memory (물리 메모리)
- Video Controller (비디오 컨트롤러)
- OnBoardDevices (메인보드 장치)
- Operating System (운영체제)
- Printer (프린터)
- Software (소프트웨어)
- Accounts (계정)
- Services (서비스)
이 시트들이 컴퓨터의 상세 정보를 담는 저장소 역할을 하며, 엑셀 파일을 열 때마다 최신 데이터로 갱신됩니다.
다음으로 개발 도구(Developer) 메뉴로 이동한 뒤, 컨트롤(Controls) 섹션에서 코드 보기(View Code)를 클릭합니다.
개발 도구 메뉴가 보이지 않는다면 파일 > 옵션 > 리본 사용자 지정으로 이동하세요. '명령 선택' 드롭다운을 모든 탭으로 변경하고, 목록에서 개발 도구를 선택한 후 추가 >> 버튼을 눌러 오른쪽 리본 목록에 추가합니다. 추가한 뒤에는 개발 도구 체크박스가 선택되어 있는지 확인하세요.
VBA 코드 편집기에 진입했다면 이제 아래 스크립트들을 모듈에 추가하기만 하면 됩니다. 실질적인 작업은 이 스크립트들이 전부 처리해 주기 때문에 직접 코드를 작성할 필요 없이 그대로 복사해서 붙여 넣으면 됩니다.
코드 복사와 붙여 넣기를 마친 후에는 시트를 불러오는 코드 몇 줄만 더 추가하면 완성입니다.
자, 복사할 준비가 되었나요? 시작해 보겠습니다.
WMI 모듈 만들기
이 코드의 원형은 Beyond Excel이라는 훌륭한 Google Sites 자료에서 가져왔습니다. 원본 예제는 WMI()라는 서브루틴으로, 컴퓨터의 네트워크 정보를 엑셀 개발 환경의 디버깅 영역에 출력합니다.
하지만 디버깅 영역에 출력되는 것은 큰 의미가 없으므로, 이 코드를 수정해 모든 정보를 이 가이드 첫 단계에서 만든 시트 중 하나에 출력하도록 변경했습니다.
코딩 탐색 영역에서 Modules 섹션과 그 아래 Module1 구성 요소를 찾을 수 있습니다. Module1을 더블클릭하여 열어주세요. Modules 폴더가 보이지 않는다면 메뉴에서 삽입(Insert) > 모듈(Module)을 선택하면 됩니다.
이 영역에는 WMI를 통해 컴퓨터의 핵심 정보를 가져와 생성한 시트에 불러오는 서브루틴들이 모두 위치하게 됩니다.
먼저 아래 코드를 코드 창의 맨 위에 독립적으로 배치하세요.
Public oWMISrvEx As Object 'SWbemServicesEx
Public oWMIObjSet As Object 'SWbemServicesObjectSet
Public oWMIObjEx As Object 'SWbemObjectEx
Public oWMIProp As Object 'SWbemProperty
Public sWQL As String 'WQL Statement
Public n
완료된 화면은 다음과 같습니다.
다음 코드를 방금 만든 선언문 아래의 Module1에 붙여 넣으세요:
Sub NetworkWMI()
sWQL = "Select * From Win32_NetworkAdapterConfiguration"
Set oWMISrvEx = GetObject("winmgmts:root/CIMV2")
Set oWMIObjSet = oWMISrvEx.ExecQuery(sWQL)
intRow = 2
strRow = Str(intRow)
ThisWorkbook.Sheets("Network").Range("A1").Value = "Name"
ThisWorkbook.Sheets("Network").Cells(1, 1).Font.Bold = True
ThisWorkbook.Sheets("Network").Range("B1").Value = "Value"
ThisWorkbook.Sheets("Network").Cells(1, 2).Font.Bold = True
For Each oWMIObjEx In oWMIObjSet
For Each oWMIProp In oWMIObjEx.Properties_
If Not IsNull(oWMIProp.Value) Then
If IsArray(oWMIProp.Value) Then
For n = LBound(oWMIProp.Value) To UBound(oWMIProp.Value)
Debug.Print oWMIProp.Name & "(" & n & ")", oWMIProp.Value(n)
ThisWorkbook.Sheets("Network").Range("A" & Trim(strRow)).Value = oWMIProp.Name
ThisWorkbook.Sheets("Network").Range("B" & Trim(strRow)).Value = oWMIProp.Value(n)
ThisWorkbook.Sheets("Network").Range("B" & Trim(strRow)).HorizontalAlignment = xlLeft
intRow = intRow + 1
strRow = Str(intRow)
Next
Else
ThisWorkbook.Sheets("Network").Range("A" & Trim(strRow)).Value = oWMIProp.Name
ThisWorkbook.Sheets("Network").Range("B" & Trim(strRow)).Value = oWMIProp.Value
ThisWorkbook.Sheets("Network").Range("B" & Trim(strRow)).HorizontalAlignment = xlLeft
intRow = intRow + 1
strRow = Str(intRow)
End If
End If
Next
'End If
Next
End Sub
이제 가이드 첫 부분에서 만든 각 시트마다 이 함수와 거의 동일한 함수를 만들어야 하며, 차이점은 몇 군데 되지 않습니다.
예를 들어 위의 NetworkWMI() 코드 전체를 복사해 코드 끝부분 바로 아래에 붙여 넣은 다음, "NetworkWMI()"를 "LogicalDiskWMI()"로 바꾸면 됩니다.
올바른 시트에 데이터가 채워지도록 코드에서 수정해야 할 부분은 몇 곳뿐입니다.
이 부분을:
sWQL = "Select * From Win32_NetworkAdapterConfiguration"
다음과 같이 변경합니다:
sWQL = "Select * From Win32_LogicalDisk"
이 네 줄을:
ThisWorkbook.Sheets("Network").Range("A1").Value = "Name"
ThisWorkbook.Sheets("Network").Cells(1, 1).Font.Bold = True
ThisWorkbook.Sheets("Network").Range("B1").Value = "Value"
ThisWorkbook.Sheets("Network").Cells(1, 2).Font.Bold = True
다음과 같이 변경합니다:
ThisWorkbook.Sheets("LogicalDisk").Range("A1").Value = "Name"
ThisWorkbook.Sheets("LogicalDisk").Cells(1, 1).Font.Bold = True
ThisWorkbook.Sheets("LogicalDisk").Range("B1").Value = "Value"
ThisWorkbook.Sheets("LogicalDisk").Cells(1, 2).Font.Bold = True
그리고 이 두 줄을:
ThisWorkbook.Sheets("Network").Range("A" & Trim(strRow)).Value = oWMIProp.Name
ThisWorkbook.Sheets("Network").Range("B" & Trim(strRow)).Value = oWMIProp.Value(n)
다음과 같이 변경합니다:
ThisWorkbook.Sheets("LogicalDisk").Range("A" & Trim(strRow)).Value = oWMIProp.Name
ThisWorkbook.Sheets("LogicalDisk").Range("B" & Trim(strRow)).Value = oWMIProp.Value(n)
마지막으로 이 세 줄도:
ThisWorkbook.Sheets("Network").Range("A" & Trim(strRow)).Value = oWMIProp.Name
ThisWorkbook.Sheets("Network").Range("B" & Trim(strRow)).Value = oWMIProp.Value
ThisWorkbook.Sheets("Network").Range("B" & Trim(strRow)).HorizontalAlignment = xlLeft
다음과 같이 변경합니다:
ThisWorkbook.Sheets("LogicalDisk").Range("A" & Trim(strRow)).Value = oWMIProp.Name
ThisWorkbook.Sheets("LogicalDisk").Range("B" & Trim(strRow)).Value = oWMIProp.Value
ThisWorkbook.Sheets("LogicalDisk").Range("B" & Trim(strRow)).HorizontalAlignment = xlLeft
이제 거의 다 왔습니다!
통합 문서의 나머지 모든 탭에 대해서도 위 과정을 반복하세요. 각 시트에 맞는 함수명은 다음과 같습니다:
- "Processor" 시트 → "ProcessorWMI()"
- "Physical Memory" 시트 → "PhysicalMemWMI()"
- "Video Controller" 시트 → "VideoControlWMI()"
- "OnBoardDevices" 시트 → "OnBoardWMI()"
- "Printer" 시트 → "PrinterWMI()"
- "Operating System" 시트 → "OperatingWMI()"
- "Software" 시트 → "SoftwareWMI()"
- "Services" 시트 → "ServicesWMI()"
각 시트의 정보에 접근하기 위해 WQL 쿼리에 사용해야 하는 특수 "Win32_" 객체는 다음과 같습니다:
- Win32_NetworkAdapterConfiguration — 네트워크 구성 설정 전체
- Win32_LogicalDisk — 디스크 용량 및 여유 공간
- Win32_Processor — CPU 사양
- Win32_PhysicalMemoryArray — RAM/설치된 메모리 크기
- Win32_VideoController — 그래픽 어댑터 및 설정
- Win32_OnBoardDevice — 메인보드 장치
- Win32_OperatingSystem — Windows 버전 및 시리얼 번호
- Win32_Printer — 설치된 프린터
- Win32_Product — 설치된 소프트웨어
- Win32_BaseService — 실행 중(또는 중지된) 서비스 목록과 서비스 경로 및 파일명
코드의 Module1 영역에서 위 함수들의 복사/붙여 넣기와 수정을 모두 마쳤다면 다음 단계로 넘어갑니다.
VBA 편집기에서 코드를 저장하는 것도 잊지 마세요! 처음에 통합 문서를 .xls 형식으로 저장했다면, Excel이 매크로 사용 가능 형식인 .xlsm으로 저장하라고 안내할 것입니다.
통합 문서 자동 로딩 설정하기
강력한 함수들을 모두 만들었다면, 이제 통합 문서를 열 때마다 이 함수들이 자동으로 실행되도록 설정하기만 하면 됩니다. 생각보다 훨씬 간단합니다.
왼쪽 개체 브라우저에서 Microsoft Excel 개체 아래에 있는 ThisWorkbook을 찾아 더블클릭하여 열어주세요.
코드 영역 상단에 드롭다운 상자 두 개가 있습니다. 왼쪽은 Workbook, 오른쪽은 Open으로 변경하세요.
그러면 Private Sub Workbook_Open()이라는 함수가 자동으로 생성됩니다.
이 함수 안에 아래 코드를 입력해 다음과 같이 만들어 주세요:
Private Sub Workbook_Open()
NetworkWMI
LogicalDiskWMI
ProcessorWMI
PhysicalMemWMI
VideoControlWMI
OnBoardWMI
PrinterWMI
SoftwareWMI
OperatingWMI
ServicesWMI
End Sub
이제 통합 문서를 열 때마다 새로 만든 모든 함수가 호출되어 컴퓨터에서 데이터를 수집하고 각각의 시트에 불러옵니다.
직접 확인해 보려면 코드를 저장하고, 코드 창을 닫은 뒤, 통합 문서를 저장하고 닫으세요. 그리고 방금 닫은 파일을 다시 열면 모든 시트가 컴퓨터에 관한 방대한 데이터로 채워져 있는 것을 발견하게 될 겁니다.
통합 문서에 매크로가 포함되어 있어 보안상 비활성화될 수 있으므로, 데이터 수집을 위해 시트 상단의 콘텐츠 사용(Enable Content)을 클릭해야 할 수도 있습니다.
주의: 이 도구는 정말 많은 데이터를 수집하기 때문에 파일을 처음 열 때 로딩에 몇 분 정도 걸릴 수 있습니다.
컴퓨터 정보 수집하기
WMI를 활용하는 것이 놀라운 이유는 위에서 수집한 데이터가 빙산의 일각에 불과하기 때문입니다. 컴퓨터 시스템의 모든 측면에 관한 정보를 담고 있는 수백 개의 WMI 클래스가 더 존재합니다.
조금 더 도전적인 성향이라면 통합 문서의 첫 번째 시트를 대시보드로 만들고, 다른 시트의 데이터를 그 대시보드에 연동하는 확장도 가능합니다.
결국 이 새로운 도구를 활용하면 대부분의 IT 전문가도 존재를 모르는 컴퓨터 시스템 정보를 수집하고 표시할 수 있으며, 제어판이나 관리 도구를 일일이 뒤지며 정보를 찾는 전문가들보다 훨씬 짧은 시간 안에 처리할 수 있게 됩니다.
이런 도구를 직접 만들어 사용해 보실 생각인가요? VBA 프로그래밍 경험이 있거나 WMI 클래스를 사용해 본 적이 있으신가요? 아래 댓글로 여러분의 경험과 아이디어를 공유해 주세요!
이미지 출처: Adriano Castelli via Shutterstock.com, Mclek via Shutterstock