• Курсы Академии Кодебай, стартующие в мае - июне, от команды The Codeby

    1. Цифровая криминалистика и реагирование на инциденты
    2. ОС Linux (DFIR) Старт: 16 мая
    3. Анализ фишинговых атак Старт: 16 мая Устройства для тестирования на проникновение Старт: 16 мая

    Скидки до 10%

    Полный список ближайших курсов ...

Статья Способы получения информации об ОС и железе с помощью Python. Часть 02: ОС Windows и subprocess. Консольная утилита wmic

Эта статья является второй частью, из небольшого цикла статей по получению информации об операционной системе и железе. И если в первой части мы получали информацию из реестра ОС Windows с помощью библиотеки winreg, то в этой статье посмотрим, как можно использовать библиотеку subprocess, в частности метод check_output. Именно с помощью данной библиотеки мы будем выполнять команды в операционной системе и с помощью утилиты wmic получать необходимые данные.

000.png

WMIC, это программа командной строки, которая представляет более удобный интерфейс для инструментария управления Windows, то есть WMI. Она основана на псевдонимах, которые упрощают использование и чтение WMI. Помимо этого, с помощью параметра CLASS можно использовать явный ввод класса схемы WMI без использования псевдонимов. Но в контексте данной статьи мы этого делать не будем, да это и не требуется. Не знаю, как долго будет находиться данная программа в операционной системе, так как с версии ОС Windows 10 21H1 она уже является нерекомендуемой. И в будущем будет заменена Windows PowerShell для WMI.

Но, этого еще не случилось окончательно, а значит сценарий, в котором можно ее использовать по прежнему работает. Так почему бы не использовать ее в своих скриптах. Давайте же приступим к написанию скрипта для получения информации об ОС, а также железе компьютера с помощью данной программы.


Что потребуется?

Если вам нужно просто вывести данные в терминал или сохранить в текстовый документ, то установки сторонних библиотек не требуется. Если же, как в данном сценарии, нужно сохранить полученные данные в документ Microsoft Word, то необходимо будет установить библиотеку python-docx. Делается это с помощью команды в терминале:

pip install python-docx

После того, как данная библиотека будет установлена, импортируем в скрипт все, что понадобиться в его работе.

Python:
import time
from platform import node
from datetime import datetime as dt
from subprocess import check_output

from docx import Document

По сути, получение данных о компьютере с помощью вывода данной программы идентично в большинстве функций данного скрипта. Поэтому, думаю, что подробно описывать каждую из них не имеет большого смысла. Опишу только первую из них, а далее буду давать небольшие комментарии и останавливаться на некоторых моментах чуть более подробно.

Для того чтобы понимать, какие данные мы получаем с помощью данной программы, следует сделать небольшой список, в котором дать пояснения, что происходит при выполнении программы с теми или иными параметрами.

/value – указывает, что выводить данные необходимо в формате параметр=значение (Description=Microsoft Kernel Debug Network Adapter)

  • wmic OS get Caption, InstallDate, Version, WindowsDirectory, LastBootUpTime /value – вывести данные об ОС, такие как дата установки, директория ОС, время последней загрузки;
  • wmic computersystem get name /value – вывести данные о компьютере, в частности о его имени;
  • wmic TIMEZONE get Caption /value – вывести данные о временной зоне, ее название;
  • wmic USERACCOUNT Where (Status="OK") get Name /value – вывести данные об имени пользователя, выбрав только те записи, у которых статус «ОК», то есть активный;
  • wmic BIOS get Version, Manufacturer, Name /value – вывести данные о BIOS: версию, производителя, имя;
  • wmic baseboard get Product, Manufacturer /value – вывести данные о материнской плате: название, производителя;
  • wmic cpu get Name, Caption, Manufacturer, SocketDesignation, MaxClockSpeed /value – вывести данные о процессоре: описание, наименование, производителя, тип сокета, частоту;
  • wmic COMPUTERSYSTEM get NumberOfLogicalProcessors /value – вывести данные о количестве логических ядер процессора;
  • wmic path win32_VideoController get Name, AdapterRAM, VideoProcessor, CurrentHorizontalResolution, CurrentVerticalResolution, CurrentRefreshRate /value – вывести данные о видеокарте, с помощью полного пути WMI, такие как: название, количество видеопамяти, разрешение (горизонтальное, вертикальное), частоту;
  • wmic COMPUTERSYSTEM get TotalPhysicalMemory /value – вывести данные о полном количестве оперативной памяти;
  • wmic MEMORYCHIP get Tag /value – вывести данные о планках, в частности об их тегах;
  • wmic MEMORYCHIP Where (Tag="{tag}") get Capacity, ConfiguredClockSpeed, Manufacturer, PartNumber, SerialNumber /value – вывести данные о чипах памяти по тегу: объем, частоту, производителя, номер партии, серийный номер;
  • wmic diskdrive get Caption /value – вывести данные о дисках: название;
  • wmic diskdrive Where (Caption="{cap}") get DeviceID, FirmwareRevision, MediaType, Partitions, SerialNumber, Size /value – сделать выборку из данных о дисках по определенному тегу: идентификатор, версию микропрогрммы, тип диска, раздел, серийный номер, размер;
  • wmic CDROM get Caption /value – вывести данные о CD-ROM: название;
  • wmic CDROM Where (Caption="{cap}") get Drive, VolumeName, VolumeSerialNumber, Size /value – сделать выборку из данных о CD-ROM по определенному наименованию: букву диска, имя тома, серийный номер тома, размер;
  • wmic NIC Where (PhysicalAdapter="TRUE") get Description /value – вывести данные о сетевых адаптерах по определенному параметру: описание;
  • wmic NIC Where (Description="{nic}") get MACAddress, Manufacturer, NetConnectionID /value – вывести данные о сетевых адаптерах по определенному описанию: MAC-адрес, производителя, идентификатор сетевого соединения;
  • wmic NICCONFIG Where (Description="{nic}") get DHCPServer, IPAddress /value – вывести данные о конфигурации по описанию: DHCP-сервер, IP-адрес.
Это, если вкратце.


Получение информации об операционной системе

Создадим функцию wmic_os() -> (dict, bool), которая на выходе возвращает словарь с полученными данными. Определим словарь, в который будем складывать полученные значения. Теперь, с помощью subprocess.check_out выполним команду, с помощью которой получим данные о названии ОС, дате установки, директории установки, времени последней загрузки. Обернем данный код в блок try – except, где обработаем ошибку декодирования. То есть, если возникает такая ошибка, меняем «utf-8» по умолчанию на кодировку «cp866».

Python:
def wmic_os() -> (dict, bool):
    os_info = dict()
    try:
        os_i = check_output("wmic OS get Caption, InstallDate, Version, WindowsDirectory, LastBootUpTime /value",
                            shell=True).decode().strip()
    except UnicodeDecodeError:
        os_i = check_output("wmic OS get Caption, InstallDate, Version, WindowsDirectory, LastBootUpTime /value",
                            shell=True).decode("cp866").strip()

Далее, создадим список со словарями, в котором распарсим полученные значения. Затем выполним еще одну команду для получения имени компьютера. Сразу же добавим полученное имя в словарь.

Python:
        if os_i:
        out = [{x.strip().split("=")[0]: x.strip().split("=")[1]} for x in os_i.splitlines() if x.strip()]
        if comp_name := check_output("wmic computersystem get name /value", shell=True).decode().strip():
            os_info.update({"ComputerName": comp_name.split("=")[1].strip()})

Запустим цикл по списку словарей. Будем брать каждый словарь и добавлять его в результирующий. Также напишем условие, которое будет проверять наличие в словаре из списка даты установки и времени последней загрузки. Их необходимо декодировать, прежде чем добавить в результирующий словарь, так как формат, в котором они возвращаются, не особо удобочитаем.

Python:
        for item in out:
            for it in item:
                if item[it]:
                    if it == "InstallDate":
                        date = dt.strptime(item[it][:len(item[it]) - 4], '%Y%m%d%H%M%S.%f').strftime(
                            "%Y-%m-%d %H:%M:%S")
                        item = {"InstallDate": date}
                    if it == "LastBootUpTime":
                        date = dt.strptime(item[it][:len(item[it]) - 4], '%Y%m%d%H%M%S.%f').strftime(
                            "%Y-%m-%d %H:%M:%S")
                        item = {"LastBootUpTime": date}
                    os_info.update(item)

Ну и получим временную зону и имя пользователя. Добавим это все в результирующий словарь и вернем его из функции, если он, конечно же, не пуст.

Python:
    if tz_get := check_output("wmic TIMEZONE get Caption /value", shell=True).decode().strip():
        tz = [{"TimeZone": x.strip().split("=")[1]} for x in tz_get.splitlines() if x.strip()]
        os_info.update(tz[0])
    if user_get := check_output('wmic USERACCOUNT Where (Status="OK") get Name /value', shell=True).decode().strip():
        user = [{"UserName": x.strip().split("=")[1]} for x in user_get.splitlines() if x.strip()]
        os_info.update(user[0])
    return os_info if os_info else False

Python:
# OS
def wmic_os() -> (dict, bool):
    os_info = dict()
    try:
        os_i = check_output("wmic OS get Caption, InstallDate, Version, WindowsDirectory, LastBootUpTime /value",
                            shell=True).decode().strip()
    except UnicodeDecodeError:
        os_i = check_output("wmic OS get Caption, InstallDate, Version, WindowsDirectory, LastBootUpTime /value",
                            shell=True).decode("cp866").strip()
    if os_i:
        out = [{x.strip().split("=")[0]: x.strip().split("=")[1]} for x in os_i.splitlines() if x.strip()]
        if comp_name := check_output("wmic computersystem get name /value", shell=True).decode().strip():
            os_info.update({"ComputerName": comp_name.split("=")[1].strip()})
        for item in out:
            for it in item:
                if item[it]:
                    if it == "InstallDate":
                        date = dt.strptime(item[it][:len(item[it]) - 4], '%Y%m%d%H%M%S.%f').strftime(
                            "%Y-%m-%d %H:%M:%S")
                        item = {"InstallDate": date}
                    if it == "LastBootUpTime":
                        date = dt.strptime(item[it][:len(item[it]) - 4], '%Y%m%d%H%M%S.%f').strftime(
                            "%Y-%m-%d %H:%M:%S")
                        item = {"LastBootUpTime": date}
                    os_info.update(item)
    if tz_get := check_output("wmic TIMEZONE get Caption /value", shell=True).decode().strip():
        tz = [{"TimeZone": x.strip().split("=")[1]} for x in tz_get.splitlines() if x.strip()]
        os_info.update(tz[0])
    if user_get := check_output('wmic USERACCOUNT Where (Status="OK") get Name /value', shell=True).decode().strip():
        user = [{"UserName": x.strip().split("=")[1]} for x in user_get.splitlines() if x.strip()]
        os_info.update(user[0])
    return os_info if os_info else False


Получение информации о BIOS

Создадим функцию bios_wmic() -> (dict, bool), которая на выходе будет возвращать словарь с полученными данными. Данная функция не особо отличается от предыдущей. Только лишь параметрами, которые передаются в программу wmic. Вывод программы обрабатывается также, как и в предыдущей функции. Затем в цикле происходит итерация по списку и добавление из него словарей в результирующий, после чего, он возвращается из функции, если не пуст.

Python:
# BIOS
def bios_wmic() -> (dict, bool):
    bios_info = dict()
    if bios := check_output("wmic BIOS get Version, Manufacturer, Name /value", shell=True).decode(). \
            strip():
        out = [{f'{x.strip().split("=")[0]}': x.strip().split("=")[1]} for x in bios.splitlines() if x.strip()]
        for item in out:
            bios_info.update(item)
        return bios_info if bios_info else False
    return False


Получение информации о материнской плате

Создадим функцию motherboard_wmic() -> (dict, bool), на выходе она возвращает словарь с полученными данными о материнской плате. Здесь получаем такие данные как наименование и производитель. После чего добавляем их в результирующий словарь и возвращаем из функции.

Python:
# Motherboard
def motherboard_wmic() -> (dict, bool):
    mb_info = dict()
    if mb_get := check_output("wmic baseboard get Product, Manufacturer /value", shell=True).decode().strip():
        out = [{f'{x.strip().split("=")[0]}': x.strip().split("=")[1]} for x in mb_get.splitlines() if x.strip()]
        for item in out:
            mb_info.update(item)
        return mb_info if mb_info else False
    return False


Получение данных о процессоре

Создадим функцию cpu_wmic() -> (dict, bool), которая возвращает словарь с полученными данными. Для начала получаем данные об имени, описании, производителе, сокете и частоте. Добавляем полученные данные в результирующий словарь. Затем выполняем команду, с помощью которой получаем количество логических процессоров использующихся в системе. На основании этого мы делаем вычисления количества физических процессоров и добавляем эти данные в результирующий словарь. После чего, если он не пуст, возвращаем из функции.

Python:
# CPU
def cpu_wmic() -> (dict, bool):
    mb_info = dict()
    if mb_get := check_output("wmic cpu get Name, Caption, Manufacturer, SocketDesignation, MaxClockSpeed /value",
                              shell=True).decode().strip():
        out = [{f'{x.strip().split("=")[0]}': x.strip().split("=")[1]} for x in mb_get.splitlines() if x.strip()]
        for item in out:
            mb_info.update(item)
    if core_all := check_output("wmic COMPUTERSYSTEM get NumberOfLogicalProcessors /value",
                                shell=True).decode().strip():
        mb_info.update({'NumberOfPhysicalProcessors': str(int(int(core_all.split("=")[1].strip()) / 2)),
                        f'{core_all.split("=")[0].strip()}': core_all.split("=")[1].strip()})
    return mb_info if mb_info else False


Получение данных о видеоадаптере

Создадим функцию gpu_wmic() -> (dict, bool). Для начала получим данные об имени, видеопамяти, разрешении, частоте и видеочипе. Теперь распарсим полученные данные и сформируем список из словарей. Все как и раньше.

Затем, в цикле, пробежимся по списку, заберем каждый словарь и добавим его в результирующий. Но, так как некоторые данные требуют перевода из байт, проверим ключи словарей. И если они соответствуют нужному параметру, выполним перевод размера. Также, объединим горизонтальное и вертикальное разрешение, чтобы они были в формате: 1920х1080, для примера. И, также добавим в результирующий словарь. После, возвращаем словарь с полученными данными, если он не пуст.

Python:
# GPU
def gpu_wmic() -> (dict, bool):
    gpu = dict()
    if output := check_output('wmic path win32_VideoController get Name, AdapterRAM, VideoProcessor, '
                              'CurrentHorizontalResolution, CurrentVerticalResolution, CurrentRefreshRate /value',
                              shell=True).decode().strip():
        out = [{x.strip().split("=")[0]: x.strip().split("=")[1]} for x in output.splitlines() if x.strip()]
        res = ""
        for vrm in out:
            for vr in vrm:
                if vr == 'AdapterRAM':
                    gpu.update({"AdapterRAM": get_size(int(vrm[vr]))})
                    continue
                if vr == 'CurrentHorizontalResolution':
                    res += f'{vrm[vr]}x'
                    continue
                if vr == 'CurrentVerticalResolution':
                    res += str(vrm[vr])
                    gpu.update({"Resolution": res})
                    continue
                gpu.update(vrm)
        return gpu if gpu else False
    return False


Получение информации об оперативной памяти

Создадим функцию memory_wmic() -> (dict, bool), которая будет возвращать словарь с полученными значениями.
Для начала получим данные о полном объеме оперативной памяти, распарсим и добавим в результирующий словарь.

Python:
def memory_wmic() -> (dict, bool):
    memory_info = dict()
    if total_memory_get := check_output("wmic COMPUTERSYSTEM get TotalPhysicalMemory /value",
                                        shell=True).decode().strip():
        total_memory = [{x.strip().split("=")[0]: get_size(int(x.strip().split("=")[1]))}
                        for x in total_memory_get.splitlines() if x.strip()]
        memory_info.update(total_memory[0])

Теперь получаем данные о тегах каждой из планок. Теги будут необходимы для того, чтобы делать выборку по каждому из них, а, следовательно, получить информацию о каждой планке по отдельности. Складываем теги в список.

Python:
    if memory_tag_get := check_output("wmic MEMORYCHIP get Tag /value", shell=True).decode().strip():
        memory_tag = [x.strip().split("=")[1] for x in memory_tag_get.splitlines() if x.strip()]

Итерируемся по списку тегов и делаем выборку о каждом чипе. Получаем объем, частоту, производителя, номер партии и серийный номер.
Из забавных моментов: получил я эти данные о своей оперативке. Сначала подумал, что ошибся, так как номер партии и серийный номер были одними и теми же. Скачал программулину, посмотрел там. Нет, все так и есть.

Python:
        for tag in memory_tag:
            info_get = check_output(f'wmic MEMORYCHIP Where (Tag="{tag}") get Capacity, ConfiguredClockSpeed, '
                                    f'Manufacturer, PartNumber, SerialNumber /value', shell=True).decode().strip()
            memory_info[tag.strip()] = dict()

Создаем для каждого тега словарь в результирующем словаре. Итерируемся по полученным данным. Переводим объем в Гб, и добавляем все, что удалось получить в результирующий словарь. После, возвращаем словарь с полученными данными из функции, если он не пуст.

Python:
            for x in info_get.splitlines():
                if x.strip():
                    if x.strip().split("=")[0] == "Capacity" and x.strip().split("=")[1]:
                        memory_info[tag.strip()].update({
                            x.strip().split("=")[0].strip(): get_size(int(x.strip().split("=")[1])).strip()
                        })
                    else:
                        memory_info[tag.strip()].update({
                            x.strip().split("=")[0].strip(): x.strip().split("=")[1].strip()
                        })
    return memory_info if memory_info else False

Python:
# Memory
def memory_wmic() -> (dict, bool):
    memory_info = dict()
    if total_memory_get := check_output("wmic COMPUTERSYSTEM get TotalPhysicalMemory /value",
                                        shell=True).decode().strip():
        total_memory = [{x.strip().split("=")[0]: get_size(int(x.strip().split("=")[1]))}
                        for x in total_memory_get.splitlines() if x.strip()]
        memory_info.update(total_memory[0])
    if memory_tag_get := check_output("wmic MEMORYCHIP get Tag /value", shell=True).decode().strip():
        memory_tag = [x.strip().split("=")[1] for x in memory_tag_get.splitlines() if x.strip()]
        for tag in memory_tag:
            info_get = check_output(f'wmic MEMORYCHIP Where (Tag="{tag}") get Capacity, ConfiguredClockSpeed, '
                                    f'Manufacturer, PartNumber, SerialNumber /value', shell=True).decode().strip()
            memory_info[tag.strip()] = dict()
            for x in info_get.splitlines():
                if x.strip():
                    if x.strip().split("=")[0] == "Capacity" and x.strip().split("=")[1]:
                        memory_info[tag.strip()].update({
                            x.strip().split("=")[0].strip(): get_size(int(x.strip().split("=")[1])).strip()
                        })
                    else:
                        memory_info[tag.strip()].update({
                            x.strip().split("=")[0].strip(): x.strip().split("=")[1].strip()
                        })
    return memory_info if memory_info else False


Получаем информацию о HDD/SSD дисках

Создадим функцию hdd_ssd_wmic() -> (dict, bool), которая возвращает словарь с полученными данными. Затем, для начала, получим описание каждого диска в системе и складируем в список. Это будет нужно, чтобы делать выборку по каждому диску, то есть, получать информацию отдельно.

Python:
def hdd_ssd_wmic() -> (dict, bool):
    disk_info = dict()
    if caption_get := check_output("wmic diskdrive get Caption /value", shell=True).decode().strip():
        caption = [x.strip().split("=")[1] for x in caption_get.splitlines() if x.strip()]

Итерируемся по описаниям, делаем выборку по каждому диску. Затем создаем словари с ключами из описаний, куда будем добавлять полученные данные. Так как у данных одинаковые ключи, необходимо их как-то разделить. Ну, а после забираем полученные данные, переводим размер диска в гигабайты, и добавляем все в результирующий словарь. После возвращаем его из функции, если данные были получены.

Python:
        for num, cap in enumerate(caption):
            if info_get := check_output(
                    f'wmic diskdrive Where (Caption="{cap}") get DeviceID, FirmwareRevision, MediaType, '
                    f'Partitions, SerialNumber, Size /value', shell=True).decode().strip():
                disk_info[f'{cap} {num}'] = dict()
                disk_info[f'{cap} {num}'].update({"Product": cap})
                for x in info_get.splitlines():
                    if x.strip():
                        if x.strip().split("=")[0] == "Size" and x.strip().split("=")[1]:
                            disk_info[f'{cap} {num}'].update({
                                f'{x.strip().split("=")[0].strip()}': get_size(int(x.strip().split("=")[1].strip()))
                            })
                        else:
                            disk_info[f'{cap} {num}'].update({
                                f'{x.strip().split("=")[0].strip()}': x.strip().split("=")[1].strip()
                            })
    return disk_info if disk_info else False

Python:
# HDD, SSD
def hdd_ssd_wmic() -> (dict, bool):
    disk_info = dict()
    if caption_get := check_output("wmic diskdrive get Caption /value", shell=True).decode().strip():
        caption = [x.strip().split("=")[1] for x in caption_get.splitlines() if x.strip()]
        for num, cap in enumerate(caption):
            if info_get := check_output(
                    f'wmic diskdrive Where (Caption="{cap}") get DeviceID, FirmwareRevision, MediaType, '
                    f'Partitions, SerialNumber, Size /value', shell=True).decode().strip():
                disk_info[f'{cap} {num}'] = dict()
                disk_info[f'{cap} {num}'].update({"Product": cap})
                for x in info_get.splitlines():
                    if x.strip():
                        if x.strip().split("=")[0] == "Size" and x.strip().split("=")[1]:
                            disk_info[f'{cap} {num}'].update({
                                f'{x.strip().split("=")[0].strip()}': get_size(int(x.strip().split("=")[1].strip()))
                            })
                        else:
                            disk_info[f'{cap} {num}'].update({
                                f'{x.strip().split("=")[0].strip()}': x.strip().split("=")[1].strip()
                            })
    return disk_info if disk_info else False


Получение информации о CD/DVD-ROM

Создадим функцию cdrom_wmic() -> (dict, bool), которая возвращает словарь с полученными значениями. В данной функции, как и в предыдущей, все происходит почти так же. Только лишь отличается команда для получения данных. А вот уже распарсивание их происходит аналогичным образом. После того, как будут получены данные по каждому устройству, возвращаем результирующий словарь из функции.

Python:
# CD-ROM
def cdrom_wmic() -> (dict, bool):
    cdrom_info = dict()
    if caption_get := check_output("wmic CDROM get Caption /value", shell=True).decode().strip():
        caption = [x.strip().split("=")[1] for x in caption_get.splitlines() if x.strip()]
        for num, cap in enumerate(caption):
            if info_get := check_output(
                    f'wmic CDROM Where (Caption="{cap}") get Drive, VolumeName, VolumeSerialNumber, Size '
                    f'/value', shell=True).decode().strip():
                cdrom_info[cap] = dict()
                cdrom_info[cap].update({"Product": cap})
                for x in info_get.splitlines():
                    if x.strip():
                        if x.strip().split("=")[0].strip() == "Size" and x.strip().split("=")[1].strip():
                            cdrom_info[cap].update({
                                f'{x.strip().split("=")[0].strip()}': get_size(int(x.strip().split("=")[1].strip()))
                            })
                        cdrom_info[cap].update({
                            f'{x.strip().split("=")[0].strip()}': x.strip().split("=")[1].strip()
                        })
    return cdrom_info if cdrom_info else False


Получение информации о сетевых интерфейсах

Создадим функцию nic_wmic() -> (dict, bool), возвращающую словарь с полученными данными. Так как в ОС Windows очень много виртуальных адаптеров, необходимо сделать выборку по тем, которые являются физическими. Для этого делаем выборку по параметру PhysicalAdapter. Если его значение TRUE, значит он является физическим. Забираем его описание и добавляем в список, для использования в последующей выборке.

Python:
def nic_wmic() -> (dict, bool):
    nic_info = dict()
    if description_get := check_output('wmic NIC Where (PhysicalAdapter="TRUE") get Description /value', shell=True). \
            decode().strip():
        description = [x.strip().split("=")[1] for x in description_get.splitlines() if x.strip()]

Итерируемся по списку с описаниями адаптеров. Делаем выборку по каждому из них. Забираем MAC-адрес, производителя, идентификатор сетевого соединения и добавляем все это в словарь. Также оборачиваем данный код в блок try – except, чтобы обработать ошибку декодирования возвращаемых из check_out данных.

Python:
        for nic in description:
            try:
                nic_d = check_output(
                    f'wmic NIC Where (Description="{nic}") get MACAddress, Manufacturer, NetConnectionID'
                    f' /value', shell=True).decode().strip()
            except UnicodeDecodeError:
                nic_d = check_output(
                    f'wmic NIC Where (Description="{nic}") get MACAddress, Manufacturer, NetConnectionID'
                    f' /value', shell=True).decode("cp866").strip()

Также делаем еще запрос и получаем по каждому адаптеру дополнительную информцию в виде DHCP-сервера (по сути, шлюза по умолчанию, хотя это и не всегда так) и IP-адес. Создаем для каждого адаптера словарь в результирующем словаре и складываем туда полученные данные. После чего возвращаем результирующий словарь из функции.

Python:
            try:
                nicconfig_d = check_output(
                    f'wmic NICCONFIG Where (Description="{nic}") get DHCPServer, IPAddress /value',
                    shell=True).decode().strip()
            except UnicodeDecodeError:
                nicconfig_d = check_output(
                    f'wmic NICCONFIG Where (Description="{nic}") get DHCPServer, IPAddress /value',
                    shell=True).decode("cp866").strip()
            nic_info[nic.strip()] = dict()
            nic_info[nic.strip()].update({"Product": nic.strip()})
            if nic_d:
                for x in nic_d.splitlines():
                    if x.strip():
                        nic_info[nic.strip()].update({
                            x.strip().split("=")[0].strip(): x.strip().split("=")[1].strip()
                        })
            if nicconfig_d:
                for x in nicconfig_d.splitlines():
                    if x.strip():
                        nic_info[nic.strip()].update({
                            x.strip().split("=")[0].strip(): x.strip().split("=")[1].strip()
                        })
    return nic_info if nic_info else False

Python:
# Network Interface
def nic_wmic() -> (dict, bool):
    nic_info = dict()
    if description_get := check_output('wmic NIC Where (PhysicalAdapter="TRUE") get Description /value', shell=True). \
            decode().strip():
        description = [x.strip().split("=")[1] for x in description_get.splitlines() if x.strip()]
        for nic in description:
            try:
                nic_d = check_output(
                    f'wmic NIC Where (Description="{nic}") get MACAddress, Manufacturer, NetConnectionID'
                    f' /value', shell=True).decode().strip()
            except UnicodeDecodeError:
                nic_d = check_output(
                    f'wmic NIC Where (Description="{nic}") get MACAddress, Manufacturer, NetConnectionID'
                    f' /value', shell=True).decode("cp866").strip()
            try:
                nicconfig_d = check_output(
                    f'wmic NICCONFIG Where (Description="{nic}") get DHCPServer, IPAddress /value',
                    shell=True).decode().strip()
            except UnicodeDecodeError:
                nicconfig_d = check_output(
                    f'wmic NICCONFIG Where (Description="{nic}") get DHCPServer, IPAddress /value',
                    shell=True).decode("cp866").strip()
            nic_info[nic.strip()] = dict()
            nic_info[nic.strip()].update({"Product": nic.strip()})
            if nic_d:
                for x in nic_d.splitlines():
                    if x.strip():
                        nic_info[nic.strip()].update({
                            x.strip().split("=")[0].strip(): x.strip().split("=")[1].strip()
                        })
            if nicconfig_d:
                for x in nicconfig_d.splitlines():
                    if x.strip():
                        nic_info[nic.strip()].update({
                            x.strip().split("=")[0].strip(): x.strip().split("=")[1].strip()
                        })
    return nic_info if nic_info else False

На этом сбор информации завершим. Можно получить еще множество самых разнообразных данных. Но, это уже по желанию. Справка о программе wmic доступна после ввода в командной строке: wmic /?. В ней можно подробно почитать, чем еще можно поживиться.


Вспомогательная функция для перевода размера

Во многих функциях данного скрипта для перевода объема оперативки, например, или объема жесткого диска используется вспомогательная функция. Давайте ее создадим: get_size(bts: int, ending='iB') -> str. На вход она получает целое число, переводит его в мега или гигабайты, и возвращает строку с полученным значением из функции.

Python:
def get_size(bts: int, ending='iB') -> str:
    size = 1024
    for item in ["", "K", "M", "G", "T", "P"]:
        if bts < size:
            return f"{bts:.2f} {item}{ending}" if bts > 0 else f"{bts:.2f} {item}B"
        bts /= size


Печать результирующих словарей в терминал и добавление в строку для сохранения в документе

Создадим функцию print_wmic(part, dict_info). На вход она получает строку с описанием словаря, который необходимо обработать, ну и, собственно, сам словарь. Те, кто читал предыдущую статью уже поняли, что используемая здесь функция аналогична точно такой же из предыдущей. Добавим глобальную строковую переменную, в которую будем складывать все, что получим из словарей: wmic_info = "".

Здесь все просто. Для начала создадим словарь синонимов, чтобы подставлять полученным значениям синонимы в удобочитаемом виде. Если где-то есть неточность перевода, вы всегда можете это исправить. Вот сам словарь:

Python:
def print_wmic(part, dict_info):
    global wmic_info
    synonyms = {"ComputerName": "Имя компьютера", "Caption": "Название", "InstallDate": "Дата установки",
                "LastBootUpTime": "Время последней загрузки", "Version": "Версия",
                "WindowsDirectory": "Директория Windows", "TimeZone": "Часовой пояс", "UserName": "Имя пользователя",
                "Manufacturer": "Производитель", "Name": "Название", "Product": "Изделие",
                "MaxClockSpeed": "Максимальная тактовая частота", "SocketDesignation": "Название сокета",
                "NumberOfPhysicalProcessors": "Количество физических процессоров", "VideoProcessor": "Видеопроцессор",
                "NumberOfLogicalProcessors": "Количество логических процессоров", "Capacity": "Емкость",
                "AdapterRAM": "Оперативная память адаптера", "CurrentRefreshRate": "Текущая частота обновления",
                "Resolution": "Разрешение", "TotalPhysicalMemory": "Общий объем физической памяти",
                "ConfiguredClockSpeed": "Настроенная тактовая частота", "PartNumber": "Номер партии",
                "SerialNumber": "Серийный номер", "DeviceID": "Идентификатор устройства", "MediaType": "Тип носителя",
                "FirmwareRevision": "Ревизия прошивки", "Partitions": "Разделы", "Size": "Объем", "Drive": "Диск",
                "VolumeName": "Имя тома", "VolumeSerialNumber": "Серийный номер тома", "MACAddress": "MAC-адрес",
                "NetConnectionID": "Идентификатор сетевого подключения", "DHCPServer": "DHCP-сервер",
                "IPAddress": "IP-адрес"}

Ну и, само тело функции. Печатаем разделитель, итерируемся по полученному словарю. Проверяем тип ключа. Если это словарь, переходим на уровень глубже и итерируемся там. Если нет, просто добавляем значение в строковую переменную. И распечатываем полученный результат.

Python:
    part += f'{"-" * 50}\n'
    for key in dict_info:
        if type(dict_info[key]) == dict:
            for item in dict_info[key]:
                part += f'{synonyms[item]}: {dict_info[key][item]}\n'
            part += "\n"
        else:
            part += f'{synonyms[key]}: {dict_info[key]}\n'
    print(part)
    wmic_info += f'{part}\n'

Python:
wmic_info = ""


def print_wmic(part, dict_info):
    global wmic_info
    synonyms = {"ComputerName": "Имя компьютера", "Caption": "Название", "InstallDate": "Дата установки",
                "LastBootUpTime": "Время последней загрузки", "Version": "Версия",
                "WindowsDirectory": "Директория Windows", "TimeZone": "Часовой пояс", "UserName": "Имя пользователя",
                "Manufacturer": "Производитель", "Name": "Название", "Product": "Изделие",
                "MaxClockSpeed": "Максимальная тактовая частота", "SocketDesignation": "Название сокета",
                "NumberOfPhysicalProcessors": "Количество физических процессоров", "VideoProcessor": "Видеопроцессор",
                "NumberOfLogicalProcessors": "Количество логических процессоров", "Capacity": "Емкость",
                "AdapterRAM": "Оперативная память адаптера", "CurrentRefreshRate": "Текущая частота обновления",
                "Resolution": "Разрешение", "TotalPhysicalMemory": "Общий объем физической памяти",
                "ConfiguredClockSpeed": "Настроенная тактовая частота", "PartNumber": "Номер партии",
                "SerialNumber": "Серийный номер", "DeviceID": "Идентификатор устройства", "MediaType": "Тип носителя",
                "FirmwareRevision": "Ревизия прошивки", "Partitions": "Разделы", "Size": "Объем", "Drive": "Диск",
                "VolumeName": "Имя тома", "VolumeSerialNumber": "Серийный номер тома", "MACAddress": "MAC-адрес",
                "NetConnectionID": "Идентификатор сетевого подключения", "DHCPServer": "DHCP-сервер",
                "IPAddress": "IP-адрес"}
    part += f'{"-" * 50}\n'
    for key in dict_info:
        if type(dict_info[key]) == dict:
            for item in dict_info[key]:
                part += f'{synonyms[item]}: {dict_info[key][item]}\n'
            part += "\n"
        else:
            part += f'{synonyms[key]}: {dict_info[key]}\n'
    print(part)
    wmic_info += f'{part}\n'


Функция main

Осталось сделать одну, не особо большую функцию, которая и будет запускать все функции скрипта, получать из них значения в виде словарей и передавать, если значения получены, в функцию печати. Здесь же мы создадим документ Microsoft Word, в который добавим для начала заголовок. И в конце функции добавим параграф с информацией, которая будет находиться в переменной wmic_info. Затем сохраняем документ и выводим данные о том, куда он сохранен, а также время работы скрипта.

Python:
def main():
    global wmic_info
    t = time.monotonic()
    document = Document()
    document.add_heading(f'Сводная информация о компьютере: {node()}', 0)

    if os_info := wmic_os():
        print_wmic("Информация об операционной системе\n", os_info)
    if bios_info := bios_wmic():
        print_wmic("Информация о BIOS\n", bios_info)
    if mb_info := motherboard_wmic():
        print_wmic("Информация о материнской плате\n", mb_info)
    if cpu_info := cpu_wmic():
        print_wmic("Информация о процессоре\n", cpu_info)
    if gpu_info := gpu_wmic():
        print_wmic("Информация о видеокарте\n", gpu_info)
    if mem_info := memory_wmic():
        print_wmic("Информация об оперативной памяти\n", mem_info)
    if drive_info := hdd_ssd_wmic():
        print_wmic("Информация о HDD и SSD\n", drive_info)
    if cd_rom_info := cdrom_wmic():
        print_wmic("Информация о CD/DVD-ROM\n", cd_rom_info)
    if nic_info := nic_wmic():
        print_wmic("Информация о физических сетевых интерфейсах\n", nic_info)

    document.add_paragraph(wmic_info)
    document.save(f'{node()}.docx')
    print(f"Собранная информация сохранена в файл: {node()}.docx")
    print(f'\nВремя работы скрипта: {time.monotonic() - t} с.')


if __name__ == "__main__":
    main()

Таким вот нехитрым способом нам удалось получить информацию о компьютере, даже более полную, чем в предыдущем скрипте, где мы получали информацию с помощью winreg из реестра.
Теперь осталось посмотреть на время работы скрипта.

001.png


Как видим, оно составляет 1.56199… то есть, почти полторы секунды. А вот время работы скрипта где мы собираем информацию winreg. Специально запустил его еще раз, для чистоты эксперимента.

002.png


Ну и да, время здесь конечно же в разы ниже: 0.0160000.

Но, как говориться, медленно, но верно. Так что, данный способ также имеет право на существование. Но, на самом деле, я бы в чем-то комбинировал эти два способа. Возможно, в самом конце, когда завершиться цикл, мы так и сделаем, чтобы сравнить скорость работы комбинированной функции.

Python:
# pip install python-docx

import time
from platform import node
from datetime import datetime as dt
from subprocess import check_output

from docx import Document


def get_size(bts: int, ending='iB') -> str:
    size = 1024
    for item in ["", "K", "M", "G", "T", "P"]:
        if bts < size:
            return f"{bts:.2f} {item}{ending}" if bts > 0 else f"{bts:.2f} {item}B"
        bts /= size


# OS
def wmic_os() -> (dict, bool):
    os_info = dict()
    try:
        os_i = check_output("wmic OS get Caption, InstallDate, Version, WindowsDirectory, LastBootUpTime /value",
                            shell=True).decode().strip()
    except UnicodeDecodeError:
        os_i = check_output("wmic OS get Caption, InstallDate, Version, WindowsDirectory, LastBootUpTime /value",
                            shell=True).decode("cp866").strip()
    if os_i:
        out = [{x.strip().split("=")[0]: x.strip().split("=")[1]} for x in os_i.splitlines() if x.strip()]
        if comp_name := check_output("wmic computersystem get name /value", shell=True).decode().strip():
            os_info.update({"ComputerName": comp_name.split("=")[1].strip()})
        for item in out:
            for it in item:
                if item[it]:
                    if it == "InstallDate":
                        date = dt.strptime(item[it][:len(item[it]) - 4], '%Y%m%d%H%M%S.%f').strftime(
                            "%Y-%m-%d %H:%M:%S")
                        item = {"InstallDate": date}
                    if it == "LastBootUpTime":
                        date = dt.strptime(item[it][:len(item[it]) - 4], '%Y%m%d%H%M%S.%f').strftime(
                            "%Y-%m-%d %H:%M:%S")
                        item = {"LastBootUpTime": date}
                    os_info.update(item)
    if tz_get := check_output("wmic TIMEZONE get Caption /value", shell=True).decode().strip():
        tz = [{"TimeZone": x.strip().split("=")[1]} for x in tz_get.splitlines() if x.strip()]
        os_info.update(tz[0])
    if user_get := check_output('wmic USERACCOUNT Where (Status="OK") get Name /value', shell=True).decode().strip():
        user = [{"UserName": x.strip().split("=")[1]} for x in user_get.splitlines() if x.strip()]
        os_info.update(user[0])
    return os_info if os_info else False


# BIOS
def bios_wmic() -> (dict, bool):
    bios_info = dict()
    if bios := check_output("wmic BIOS get Version, Manufacturer, Name /value", shell=True).decode(). \
            strip():
        out = [{f'{x.strip().split("=")[0]}': x.strip().split("=")[1]} for x in bios.splitlines() if x.strip()]
        for item in out:
            bios_info.update(item)
        return bios_info if bios_info else False
    return False


# Motherboard
def motherboard_wmic() -> (dict, bool):
    mb_info = dict()
    if mb_get := check_output("wmic baseboard get Product, Manufacturer /value", shell=True).decode().strip():
        out = [{f'{x.strip().split("=")[0]}': x.strip().split("=")[1]} for x in mb_get.splitlines() if x.strip()]
        for item in out:
            mb_info.update(item)
        return mb_info if mb_info else False
    return False


# CPU
def cpu_wmic() -> (dict, bool):
    mb_info = dict()
    if mb_get := check_output("wmic cpu get Name, Caption, Manufacturer, SocketDesignation, MaxClockSpeed /value",
                              shell=True).decode().strip():
        out = [{f'{x.strip().split("=")[0]}': x.strip().split("=")[1]} for x in mb_get.splitlines() if x.strip()]
        for item in out:
            mb_info.update(item)
    if core_all := check_output("wmic COMPUTERSYSTEM get NumberOfLogicalProcessors /value",
                                shell=True).decode().strip():
        mb_info.update({'NumberOfPhysicalProcessors': str(int(int(core_all.split("=")[1].strip()) / 2)),
                        f'{core_all.split("=")[0].strip()}': core_all.split("=")[1].strip()})
    return mb_info if mb_info else False


# GPU
def gpu_wmic() -> (dict, bool):
    gpu = dict()
    if output := check_output('wmic path win32_VideoController get Name, AdapterRAM, VideoProcessor, '
                              'CurrentHorizontalResolution, CurrentVerticalResolution, CurrentRefreshRate /value',
                              shell=True).decode().strip():
        out = [{x.strip().split("=")[0]: x.strip().split("=")[1]} for x in output.splitlines() if x.strip()]
        res = ""
        for vrm in out:
            for vr in vrm:
                if vr == 'AdapterRAM':
                    gpu.update({"AdapterRAM": get_size(int(vrm[vr]))})
                    continue
                if vr == 'CurrentHorizontalResolution':
                    res += f'{vrm[vr]}x'
                    continue
                if vr == 'CurrentVerticalResolution':
                    res += str(vrm[vr])
                    gpu.update({"Resolution": res})
                    continue
                gpu.update(vrm)
        return gpu if gpu else False
    return False


# Memory
def memory_wmic() -> (dict, bool):
    memory_info = dict()
    if total_memory_get := check_output("wmic COMPUTERSYSTEM get TotalPhysicalMemory /value",
                                        shell=True).decode().strip():
        total_memory = [{x.strip().split("=")[0]: get_size(int(x.strip().split("=")[1]))}
                        for x in total_memory_get.splitlines() if x.strip()]
        memory_info.update(total_memory[0])
    if memory_tag_get := check_output("wmic MEMORYCHIP get Tag /value", shell=True).decode().strip():
        memory_tag = [x.strip().split("=")[1] for x in memory_tag_get.splitlines() if x.strip()]
        for tag in memory_tag:
            info_get = check_output(f'wmic MEMORYCHIP Where (Tag="{tag}") get Capacity, ConfiguredClockSpeed, '
                                    f'Manufacturer, PartNumber, SerialNumber /value', shell=True).decode().strip()
            memory_info[tag.strip()] = dict()
            for x in info_get.splitlines():
                if x.strip():
                    if x.strip().split("=")[0] == "Capacity" and x.strip().split("=")[1]:
                        memory_info[tag.strip()].update({
                            x.strip().split("=")[0].strip(): get_size(int(x.strip().split("=")[1])).strip()
                        })
                    else:
                        memory_info[tag.strip()].update({
                            x.strip().split("=")[0].strip(): x.strip().split("=")[1].strip()
                        })
    return memory_info if memory_info else False


# HDD, SSD
def hdd_ssd_wmic() -> (dict, bool):
    disk_info = dict()
    if caption_get := check_output("wmic diskdrive get Caption /value", shell=True).decode().strip():
        caption = [x.strip().split("=")[1] for x in caption_get.splitlines() if x.strip()]
        for num, cap in enumerate(caption):
            if info_get := check_output(
                    f'wmic diskdrive Where (Caption="{cap}") get DeviceID, FirmwareRevision, MediaType, '
                    f'Partitions, SerialNumber, Size /value', shell=True).decode().strip():
                disk_info[f'{cap} {num}'] = dict()
                disk_info[f'{cap} {num}'].update({"Product": cap})
                for x in info_get.splitlines():
                    if x.strip():
                        if x.strip().split("=")[0] == "Size" and x.strip().split("=")[1]:
                            disk_info[f'{cap} {num}'].update({
                                f'{x.strip().split("=")[0].strip()}': get_size(int(x.strip().split("=")[1].strip()))
                            })
                        else:
                            disk_info[f'{cap} {num}'].update({
                                f'{x.strip().split("=")[0].strip()}': x.strip().split("=")[1].strip()
                            })
    return disk_info if disk_info else False


# CD-ROM
def cdrom_wmic() -> (dict, bool):
    cdrom_info = dict()
    if caption_get := check_output("wmic CDROM get Caption /value", shell=True).decode().strip():
        caption = [x.strip().split("=")[1] for x in caption_get.splitlines() if x.strip()]
        for num, cap in enumerate(caption):
            if info_get := check_output(
                    f'wmic CDROM Where (Caption="{cap}") get Drive, VolumeName, VolumeSerialNumber, Size '
                    f'/value', shell=True).decode().strip():
                cdrom_info[cap] = dict()
                cdrom_info[cap].update({"Product": cap})
                for x in info_get.splitlines():
                    if x.strip():
                        if x.strip().split("=")[0].strip() == "Size" and x.strip().split("=")[1].strip():
                            cdrom_info[cap].update({
                                f'{x.strip().split("=")[0].strip()}': get_size(int(x.strip().split("=")[1].strip()))
                            })
                        cdrom_info[cap].update({
                            f'{x.strip().split("=")[0].strip()}': x.strip().split("=")[1].strip()
                        })
    return cdrom_info if cdrom_info else False


# Network Interface
def nic_wmic() -> (dict, bool):
    nic_info = dict()
    if description_get := check_output('wmic NIC Where (PhysicalAdapter="TRUE") get Description /value', shell=True). \
            decode().strip():
        description = [x.strip().split("=")[1] for x in description_get.splitlines() if x.strip()]
        for nic in description:
            try:
                nic_d = check_output(
                    f'wmic NIC Where (Description="{nic}") get MACAddress, Manufacturer, NetConnectionID'
                    f' /value', shell=True).decode().strip()
            except UnicodeDecodeError:
                nic_d = check_output(
                    f'wmic NIC Where (Description="{nic}") get MACAddress, Manufacturer, NetConnectionID'
                    f' /value', shell=True).decode("cp866").strip()
            try:
                nicconfig_d = check_output(
                    f'wmic NICCONFIG Where (Description="{nic}") get DHCPServer, IPAddress /value',
                    shell=True).decode().strip()
            except UnicodeDecodeError:
                nicconfig_d = check_output(
                    f'wmic NICCONFIG Where (Description="{nic}") get DHCPServer, IPAddress /value',
                    shell=True).decode("cp866").strip()
            nic_info[nic.strip()] = dict()
            nic_info[nic.strip()].update({"Product": nic.strip()})
            if nic_d:
                for x in nic_d.splitlines():
                    if x.strip():
                        nic_info[nic.strip()].update({
                            x.strip().split("=")[0].strip(): x.strip().split("=")[1].strip()
                        })
            if nicconfig_d:
                for x in nicconfig_d.splitlines():
                    if x.strip():
                        nic_info[nic.strip()].update({
                            x.strip().split("=")[0].strip(): x.strip().split("=")[1].strip()
                        })
    return nic_info if nic_info else False


wmic_info = ""


def print_wmic(part, dict_info):
    global wmic_info
    synonyms = {"ComputerName": "Имя компьютера", "Caption": "Название", "InstallDate": "Дата установки",
                "LastBootUpTime": "Время последней загрузки", "Version": "Версия",
                "WindowsDirectory": "Директория Windows", "TimeZone": "Часовой пояс", "UserName": "Имя пользователя",
                "Manufacturer": "Производитель", "Name": "Название", "Product": "Изделие",
                "MaxClockSpeed": "Максимальная тактовая частота", "SocketDesignation": "Название сокета",
                "NumberOfPhysicalProcessors": "Количество физических процессоров", "VideoProcessor": "Видеопроцессор",
                "NumberOfLogicalProcessors": "Количество логических процессоров", "Capacity": "Емкость",
                "AdapterRAM": "Оперативная память адаптера", "CurrentRefreshRate": "Текущая частота обновления",
                "Resolution": "Разрешение", "TotalPhysicalMemory": "Общий объем физической памяти",
                "ConfiguredClockSpeed": "Настроенная тактовая частота", "PartNumber": "Номер партии",
                "SerialNumber": "Серийный номер", "DeviceID": "Идентификатор устройства", "MediaType": "Тип носителя",
                "FirmwareRevision": "Ревизия прошивки", "Partitions": "Разделы", "Size": "Объем", "Drive": "Диск",
                "VolumeName": "Имя тома", "VolumeSerialNumber": "Серийный номер тома", "MACAddress": "MAC-адрес",
                "NetConnectionID": "Идентификатор сетевого подключения", "DHCPServer": "DHCP-сервер",
                "IPAddress": "IP-адрес"}
    part += f'{"-" * 50}\n'
    for key in dict_info:
        if type(dict_info[key]) == dict:
            for item in dict_info[key]:
                part += f'{synonyms[item]}: {dict_info[key][item]}\n'
            part += "\n"
        else:
            part += f'{synonyms[key]}: {dict_info[key]}\n'
    print(part)
    wmic_info += f'{part}\n'


def main():
    global wmic_info
    t = time.monotonic()
    document = Document()
    document.add_heading(f'Сводная информация о компьютере: {node()}', 0)

    if os_info := wmic_os():
        print_wmic("Информация об операционной системе\n", os_info)
    if bios_info := bios_wmic():
        print_wmic("Информация о BIOS\n", bios_info)
    if mb_info := motherboard_wmic():
        print_wmic("Информация о материнской плате\n", mb_info)
    if cpu_info := cpu_wmic():
        print_wmic("Информация о процессоре\n", cpu_info)
    if gpu_info := gpu_wmic():
        print_wmic("Информация о видеокарте\n", gpu_info)
    if mem_info := memory_wmic():
        print_wmic("Информация об оперативной памяти\n", mem_info)
    if drive_info := hdd_ssd_wmic():
        print_wmic("Информация о HDD и SSD\n", drive_info)
    if cd_rom_info := cdrom_wmic():
        print_wmic("Информация о CD/DVD-ROM\n", cd_rom_info)
    if nic_info := nic_wmic():
        print_wmic("Информация о физических сетевых интерфейсах\n", nic_info)

    document.add_paragraph(wmic_info)
    document.save(f'{node()}.docx')
    print(f"Собранная информация сохранена в файл: {node()}.docx")
    print(f'\nВремя работы скрипта: {time.monotonic() - t} с.')


if __name__ == "__main__":
    main()

А на этом, пожалуй, все.

Спасибо за внимание. Надеюсь, данная информация будет вам полезна
 

Вложения

  • wmic_win_merge.zip
    3,5 КБ · Просмотры: 97
Последнее редактирование:
  • Нравится
Реакции: InternetMC

InternetMC

Green Team
13.01.2019
11
4
BIT
146
Приветствую, пишет ошибку в строке 146.
Traceback (most recent call last):
Файл "C:\Users\Alex\Desktop\os_infa.py", строка 276, из <module> main()
Файл "C:\Users\Alex\Desktop\os_infa.py", строка 262, из <module> if drive_info := hdd_ssd_wmic():
Файл "C:\Users\Alex\Desktop\os_infa.py", строка 146, из <module> f'{x.strip().split("=")[0].strip()}': get_size(int(x.strip().split("=")[1])).strip()
builtins.ValueError: invalid literal for int() with base 10: ''
 

Johan Van

Green Team
13.06.2020
354
663
BIT
186
Приветствую, пишет ошибку в строке 146.
Traceback (most recent call last):
Файл "C:\Users\Alex\Desktop\os_infa.py", строка 276, из <module> main()
Файл "C:\Users\Alex\Desktop\os_infa.py", строка 262, из <module> if drive_info := hdd_ssd_wmic():
Файл "C:\Users\Alex\Desktop\os_infa.py", строка 146, из <module> f'{x.strip().split("=")[0].strip()}': get_size(int(x.strip().split("=")[1])).strip()
builtins.ValueError: invalid literal for int() with base 10: ''

Привет.

Попробуйте заменить эту строку на это:

Python:
disk_info[f'{cap} {num}'].update({
                        f'{x.strip().split("=")[0].strip()}': get_size(int(x.strip().split("=")[1].strip()))
                    })

Возможно я поставил не туда strip(). Если это не поможет, посмотрите, что возвращает парсинг строки:

print(x.strip().split("=")[1].strip())

Добавьте этот код после условия if и посмотрите, какие распечатываются значения. Возможно, что возвращается значение, которое не может быть переведено в целое число.
Например, пустое. Отпишитесь, что у вас получиться. Действительно ли это у меня ошибка в strip() или необходимо добавить обработку ошибки.
 

InternetMC

Green Team
13.01.2019
11
4
BIT
146
Привет.

Попробуйте заменить эту строку на это:

Python:
disk_info[f'{cap} {num}'].update({
                        f'{x.strip().split("=")[0].strip()}': get_size(int(x.strip().split("=")[1].strip()))
                    })

Возможно я поставил не туда strip(). Если это не поможет, посмотрите, что возвращает парсинг строки:

print(x.strip().split("=")[1].strip())

Добавьте этот код после условия if и посмотрите, какие распечатываются значения. Возможно, что возвращается значение, которое не может быть переведено в целое число.
Например, пустое. Отпишитесь, что у вас получиться. Действительно ли это у меня ошибка в strip() или необходимо добавить обработку ошибки.
Парсинг строки действительно возвращает много пустых строк и только одно числовое значение. 1000202273280. Это мой диск на 1 Тб. А пустые значения это USB Device.
 

Johan Van

Green Team
13.06.2020
354
663
BIT
186
Парсинг строки действительно возвращает много пустых строк и только одно числовое значение. 1000202273280. Это мой диск на 1 Тб. А пустые значения это USB Device.
ну тогда да. тогда надо обработку ошибки туда добавить. try - except. сейчас, гляну и код скину.
 

Johan Van

Green Team
13.06.2020
354
663
BIT
186
Парсинг строки действительно возвращает много пустых строк и только одно числовое значение. 1000202273280. Это мой диск на 1 Тб. А пустые значения это USB Device.

примерно так:

Python:
        for x in info_get.splitlines():
            if x.strip():
                if x.strip().split("=")[0] == "Size":
                    try:
                        disk_info[f'{cap} {num}'].update({
                            f'{x.strip().split("=")[0].strip()}': get_size(int(x.strip().split("=")[1].strip()))
                        })
                    except ValueError:
                        disk_info[f'{cap} {num}'].update({
                            f'{x.strip().split("=")[0].strip()}': ""
                        })

Поменяйте эти строки. Если не сложно, отпишитесь, что получиться. У меня то все нормально проходит ))
 

Johan Van

Green Team
13.06.2020
354
663
BIT
186
Теперь все работает как надо. Обработку ошибок поставил там и там.

Вообще-то один. Но там везде пустые значения кроме "Изделие: Optiarc DVD RW AD-5240S ATA Device".
Надо посмотреть. Что то у меня видно в коде не так. Требуется перепроверка, наверное. Спасибо за обратную связь
 
Мы в соцсетях:

Обучение наступательной кибербезопасности в игровой форме. Начать игру!