import subprocess
import json

def run_powershell(cmd):
    """Run PowerShell command and return output."""
    process = subprocess.Popen(
        ["powershell.exe", "-NoProfile", "-ExecutionPolicy", "Bypass", "-Command", cmd],
        stdout=subprocess.PIPE, stderr=subprocess.PIPE
    )
    out, err = process.communicate()
    return out.decode("utf-8", "replace").strip()

# Get Serial Number
serial_cmd = "(Get-CimInstance Win32_BIOS).SerialNumber"
serial = run_powershell(serial_cmd)
if not serial:
    serial = "Unknown"

# Get RAM Module Info as JSON
ram_cmd = "Get-CimInstance Win32_PhysicalMemory | Select DeviceLocator, Manufacturer, PartNumber, Capacity | ConvertTo-Json"
ram_json = run_powershell(ram_cmd)

try:
    ram_data = json.loads(ram_json)
except:
    ram_data = []

# Normalize list if only one module is found
if isinstance(ram_data, dict):
    ram_data = [ram_data]

# Calculate Total RAM
total_ram_gb = 0.0
for stick in ram_data:
    try:
        total_ram_gb += float(stick["Capacity"]) / (1024**3)
    except:
        pass
total_ram_gb = round(total_ram_gb, 2)

# Output
print "=========================================="
print " System Serial Number: {}".format(serial)
print " Total Installed RAM : {} GB".format(total_ram_gb)
print "=========================================="
print " RAM Module Details:"

if len(ram_data) == 0:
    print "  (No RAM modules detected — BIOS/WMI lock or restricted SYSTEM privileges)"
else:
    i = 1
    for stick in ram_data:
        slot = stick.get("DeviceLocator", "").strip()
        man  = stick.get("Manufacturer", "").strip()
        part = stick.get("PartNumber", "").strip()
        cap  = round(float(stick.get("Capacity", 0)) / (1024**3), 2)
        print "  Module {} : Slot='{}' Manufacturer='{}' PartNumber='{}' Capacity={} GB".format(i, slot, man, part, cap)
        i += 1
