135 lines
5.0 KiB
Python
135 lines
5.0 KiB
Python
import wmi
|
|
import requests
|
|
import json
|
|
import socket
|
|
import platform
|
|
import sys
|
|
import time
|
|
|
|
def collect_specs():
|
|
try:
|
|
c = wmi.WMI()
|
|
computer = c.Win32_ComputerSystem()[0]
|
|
os_info = c.Win32_OperatingSystem()[0]
|
|
proc = c.Win32_Processor()[0]
|
|
board = c.Win32_BaseBoard()[0]
|
|
|
|
# 1. 상세 GPU 정보 수집 (모든 그래픽 카드)
|
|
gpu_list = []
|
|
for g in c.Win32_VideoController():
|
|
gpu_list.append(g.Name)
|
|
gpu_info = ", ".join(gpu_list) if gpu_list else "N/A"
|
|
|
|
# 2. 모든 저장장치 정보 수집 및 SSD/HDD 구분
|
|
storage_list = []
|
|
|
|
# Windows 8 이상에서 작동하는 상세 저장소 정보 수집 시도
|
|
physical_disks = {}
|
|
try:
|
|
storage_c = wmi.WMI(namespace="Root\\Microsoft\\Windows\\Storage")
|
|
for d in storage_c.MSFT_PhysicalDisk():
|
|
# MediaType: 3(HDD), 4(SSD), 0(Unspecified)
|
|
physical_disks[d.DeviceId] = d.MediaType
|
|
except:
|
|
pass
|
|
|
|
for d in c.Win32_DiskDrive():
|
|
size_gb = round(float(d.Size) / (1024**3)) if d.Size else 0
|
|
|
|
# 미디어 타입 판단
|
|
media_type = physical_disks.get(str(d.Index), 0)
|
|
prefix = ""
|
|
if media_type == 4:
|
|
prefix = "[SSD] "
|
|
elif media_type == 3:
|
|
prefix = "[HDD] "
|
|
else:
|
|
# 힌트가 없을 경우 모델명으로 추측
|
|
cap = d.Caption.upper()
|
|
if "SSD" in cap or "NVME" in cap or "FLASH" in cap:
|
|
prefix = "[SSD] "
|
|
else:
|
|
prefix = "[HDD] "
|
|
|
|
storage_list.append(f"{prefix}{d.Caption} ({size_gb}GB)")
|
|
|
|
# DB 필드(SSD1, SSD2, SSD3)에 나눠 담기
|
|
storage1 = storage_list[0] if len(storage_list) > 0 else "N/A"
|
|
storage2 = storage_list[1] if len(storage_list) > 1 else ""
|
|
storage3 = storage_list[2] if len(storage_list) > 2 else ""
|
|
|
|
# 실시간 데이터 추출
|
|
specs = {
|
|
"메인보드": f"{board.Manufacturer} {board.Product}".strip(),
|
|
"CPU": proc.Name.strip(),
|
|
"RAM": f"{round(float(computer.TotalPhysicalMemory) / (1024**3))}GB",
|
|
"OS": os_info.Caption,
|
|
"GPU": gpu_info,
|
|
"SSD1": storage1,
|
|
"SSD2": storage2,
|
|
"SSD3": storage3,
|
|
"비고": "실시간 에이전트(EXE) 자동 수집"
|
|
}
|
|
return specs
|
|
except Exception as e:
|
|
print(f"데이터 수집 중 오류 발생: {e}")
|
|
return None
|
|
|
|
def send_data(specs, server_url, asset_code):
|
|
try:
|
|
# 전송 데이터에 자산코드 추가 (식별용)
|
|
specs["자산코드"] = asset_code
|
|
print(f"\n📡 서버로 전송 중... ({server_url})")
|
|
response = requests.post(server_url, json=specs, timeout=10)
|
|
if response.status_code == 200:
|
|
print("✅ 전송 성공! ITAM 시스템에서 확인하세요.")
|
|
else:
|
|
print(f"❌ 전송 실패: 서버 응답 코드 {response.status_code}")
|
|
except Exception as e:
|
|
print(f"❌ 서버 연결 오류: {e}")
|
|
print("서버가 켜져 있는지, URL이 맞는지 확인해주세요.")
|
|
|
|
if __name__ == "__main__":
|
|
print("========================================")
|
|
print(" ITAM PC 실시간 사양 수집 에이전트 (v1.1)")
|
|
print("========================================\n")
|
|
|
|
# 1. 정보 수집
|
|
print("🔍 하드웨어 정보를 읽어오는 중...")
|
|
data = collect_specs()
|
|
|
|
if data:
|
|
print("\n[수집된 실제 사양]")
|
|
display_map = {
|
|
"메인보드": "메인보드",
|
|
"CPU": "CPU",
|
|
"RAM": "RAM",
|
|
"OS": "OS",
|
|
"GPU": "GPU",
|
|
"SSD1": "Storage 1",
|
|
"SSD2": "Storage 2",
|
|
"SSD3": "Storage 3",
|
|
"비고": "비고"
|
|
}
|
|
for key, value in data.items():
|
|
if value: # 값이 있는 경우만 표시
|
|
label = display_map.get(key, key)
|
|
print(f" - {label}: {value}")
|
|
|
|
print("\n" + "="*40)
|
|
asset_code = input("등록할 자산번호를 입력하세요 (예: PC-001): ").strip()
|
|
if not asset_code:
|
|
print("❌ 자산번호 없이는 전송할 수 없습니다.")
|
|
else:
|
|
server_ip = input("서버 IP를 입력하세요 (기본값 localhost): ").strip()
|
|
if not server_ip: server_ip = "localhost"
|
|
|
|
target_url = f"http://{server_ip}:3000/api/agent/collect"
|
|
|
|
confirm = input("\n위 정보를 서버로 전송할까요? (y/n): ")
|
|
if confirm.lower() == 'y':
|
|
send_data(data, target_url, asset_code)
|
|
|
|
print("\n5초 후 프로그램이 종료됩니다...")
|
|
time.sleep(5)
|