Привет, Хабр! Типичная ситуация: начальство требует полный отчёт по всему парку техники или только устроились в организацию с крупным парком машин, нужно сформировать понимание, с чем вы работаете. Вручную обходить 100+ рабочих мест - совсем не вариант.

В статье я поделюсь PowerShell-скриптом, который:

  • Сам обойдет все машины в сети

  • Соберёт подробную информацию о конфигурации

  • Сгенерирует удобные для восприятия HTML-отчёты

  • Складирует всё в вашу сетевую папку для удобства

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

Возможности скрипта

Скрипт собирает комплексную информацию о системе:

  • Информация об операционной системе (версия, архитектура, время работы)

  • Данные о BIOS и производителе оборудования Аппаратное обеспечение:

  • Процессор (модель, ядра/потоки, загрузка)

  • Оперативная память (объем, модули, использование)

  • Графические процессоры (модель, память, драйверы)

  • Накопители (модель, разделы, свободное пространство) Сетевые адаптеры:

  • Активные сетевые адаптеры

  • IP и MAC-адреса

  • Скорость соединения Доп информация:

  • Версия PowerShell

  • Логические диски и процент их заполнения

Назначение скрипта

Скрипт выполняет следующие задачи:

  • Собирает основную конфигурацию с удалённых машин

  • Сохраняет данные в структурированном HTML-формате

  • Централизованно хранит отчёты в вашей сетевой папке

  • Автоматически удаляет устаревшие отчёты

  • Логирует все этапы работы

Архитектура решения

Скрипт имеет следующую структуру:

  1. Контроллер - основной скрипт, который запускается на машине админа

  2. Агенты - функции, выполняемые на удалённых компьютерах

Детальный разбор компонентов

Я разберу лишь основные функции скрипта, тк нагружать вас во многом бесполезным кодом - нет смысла. Полный скрипт:

Скрытый текст
$centralLogsFolder = "\\сервер\общая_папка\Logs"
$maxReportsPerComputer = 5
$logFile = Join-Path $centralLogsFolder "InventoryScript_$(Get-Date -Format 'yyyyMMdd').log"

# Функция для логирования
function Write-Log {
    param(
        [string]$message,
        [string]$level = "INFO"
    )
    $timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
    $logEntry = "[$timestamp][$level] $message"
    Add-Content -Path $logFile -Value $logEntry
    Write-Host $logEntry -ForegroundColor $(if ($level -eq "ERROR") { "Red" } elseif ($level -eq "WARNING") { "Yellow" } else { "White" })
}

# Создаём основную папку для логов, если её нет
if (!(Test-Path $centralLogsFolder)) {
    try {
        New-Item -ItemType Directory -Path $centralLogsFolder -Force | Out-Null
        Write-Log "Создана центральная папка для логов: $centralLogsFolder"
    }
    catch {
        Write-Log "Не удалось создать центральную папку для логов: $_" -level "ERROR"
        exit 1
    }
}

# Получаем список компьютеров
try {
    # Способ 1: Из Active Directory (раскомментируйте нужный)
    # $computers = Get-ADComputer -Filter * | Select-Object -ExpandProperty Name
    
    # Способ 2: Из файла
    $computers = Get-Content "C:\path\to\computers.txt" | Where-Object { $_ -notmatch '^\s*#' -and $_ -ne '' }
    
    # Способ 3: Вручную указать список
    # $computers = @("COMPUTER1", "COMPUTER2", "COMPUTER3")

    if (-not $computers) {
        Write-Log "Не найдено компьютеров для обработки" -level "WARNING"
        exit 1
    }
    
    Write-Log "Получен список компьютеров для обработки: $($computers.Count) шт."
}
catch {
    Write-Log "Не удалось получить список компьютеров: $_" -level "ERROR"
    exit 1
}

# Запрашиваем учётные данные
$cred = Get-Credential -Message "Введите учётные данные с правами администратора на целевых компьютерах"
if (-not $cred) {
    Write-Log "Не введены учётные данные" -level "ERROR"
    exit 1
}

# Функция для удалённого сбора информации
function Get-RemoteSystemInventory {
    param(
        [string]$computerName,
        [string]$outputDir,
        [int]$maxReports,
        [pscredential]$credential
    )
    
    $session = $null
    try {
        # Проверяем доступность компьютера
        if (-not (Test-Connection -ComputerName $computerName -Count 2 -Quiet)) {
            Write-Log "Компьютер $computerName недоступен по сети" -level "WARNING"
            return
        }

        # Создаём сессию PSRemoting
        $sessionParams = @{
            ComputerName = $computerName
            Credential = $credential
            ErrorAction = 'Stop'
        }
        
        # Пробуем подключиться (добавляем проверку для WinRM)
        try {
            $session = New-PSSession @sessionParams
        }
        catch {
            # Если WinRM отключен, пробуем через WMI
            Write-Log "Не удалось подключиться к $computerName через PSRemoting, пробуем WMI" -level "WARNING"
            
            $scriptBlock = {
                param($outputDir, $maxReports)
                # Встроенный код функции Get-SystemInventory (см. ниже)
                # ... (всё содержимое функции Get-SystemInventory)
            }

            Invoke-Command -ComputerName $computerName -Credential $credential -ScriptBlock $scriptBlock -ArgumentList $outputDir, $maxReports -ErrorAction Stop
            Write-Log "Успешно собраны данные с $computerName через WMI" -level "INFO"
            return
        }

        # Подготовка аргументов
        $remoteOutputDir = Join-Path $outputDir $computerName
        $arguments = @($remoteOutputDir, $maxReports)

        # Выполняем команду на удалённом компьютере
        $result = Invoke-Command -Session $session -ScriptBlock ${function:Get-SystemInventory} -ArgumentList $arguments -ErrorAction Stop
        
        Write-Log "Успешно собраны данные с компьютера $computerName" -level "INFO"
    }
    catch {
        Write-Log "Ошибка при работе с компьютером $computerName : $_" -level "ERROR"
    }
    finally {
        if ($session) {
            Remove-PSSession -Session $session -ErrorAction SilentlyContinue
        }
    }
}

# Основная функция сбора данных (будет выполняться на удалённых машинах)
function Get-SystemInventory {
    param(
        [string]$outputDir,
        [int]$maxReports
    )
    
    try {
        $computerName = $env:COMPUTERNAME
        $fileName = "Inventory_$(Get-Date -Format 'yyyyMMdd-HHmmss').html"
        $fullOutputDir = Join-Path $outputDir $computerName

        # Создаём папку и чистим старые отчёты
        if (!(Test-Path $fullOutputDir)) { 
            New-Item -ItemType Directory -Path $fullOutputDir -Force | Out-Null 
        }
        
        Get-ChildItem $fullOutputDir -Filter "Inventory_*.html" | 
            Sort-Object CreationTime -Descending | 
            Select-Object -Skip $maxReports | 
            Remove-Item -Force -ErrorAction SilentlyContinue

        # Собираем основные данные
        $os = Get-CimInstance Win32_OperatingSystem
        $cpu = Get-CimInstance Win32_Processor
        $mem = Get-CimInstance Win32_PhysicalMemory
        $totalGB = [math]::Round(($mem | Measure-Object -Property Capacity -Sum).Sum /1GB, 2)

        # Получаем данные о загрузке CPU
        $cpuUsage = "Ошибка получения данных"
        try {
            $cpuUsage = (Get-Counter '\Processor(_Total)\% Processor Time' -ErrorAction Stop).CounterSamples.CookedValue.ToString("N2")
        } catch {
            try {
                $cpuUsage = (Get-WmiObject Win32_Processor | Measure-Object -Property LoadPercentage -Average).Average.ToString("N2")
            } catch {
                $cpuUsage = "Ошибка получения данных"
            }
        }

        $gpus = Get-CimInstance Win32_VideoController
        $networkAdapters = Get-NetAdapter | Where-Object { $_.Status -eq "Up" } | ForEach-Object {
            $ipAddress = (Get-NetIPAddress -InterfaceIndex $_.ifIndex -AddressFamily IPv4).IPAddress
            [PSCustomObject]@{
                Name = $_.Name
                Interface = $_.InterfaceDescription
                Status = $_.Status
                Speed = "$([math]::Round($_.Speed/1MB, 2)) Mbps"
                MAC = $_.MacAddress
                IP = $ipAddress
            }
        }

        $disks = Get-Disk | ForEach-Object {
            $partitions = Get-Partition -DiskNumber $_.DiskNumber | ForEach-Object {
                $vol = Get-Volume -Partition $_
                $freeSpacePercent = if ($vol.Size -gt 0) { [math]::Round(($vol.SizeRemaining / $vol.Size) * 100, 2) } else { 0 }
                $freeSpaceClass = if ($freeSpacePercent -lt 10) { "err" } elseif ($freeSpacePercent -lt 20) { "warn" } else { "" }
                "<span class='$freeSpaceClass'>$($_.DriveLetter) $([math]::Round($_.Size/1GB))GB ($([math]::Round($vol.SizeRemaining/1GB))GB свободно, $freeSpacePercent%)</span>"
            }
            [PSCustomObject]@{
                Model = $_.FriendlyName
                Size = [math]::Round($_.Size/1GB)
                Health = $_.HealthStatus
                Partitions = $partitions -join '<br>'
            }
        }

        # Генерируем HTML (как в вашем оригинальном скрипте)
        $html = @"
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Системный отчет - $computerName</title>
<style>
body{font-family:Segoe UI;margin:20px}
h1,h2{color:#0066cc}
table{width:100%;border-collapse:collapse}
th,td{padding:8px;text-align:left;border-bottom:1px solid #ddd}
.warn{color:orange}
.err{color:red}
.info{color:#0066cc}
.disk-info{background-color:#f9f9f9}
.gpu-info{background-color:#f0f8ff}
.network-info{background-color:#fff8f0}
</style>
</head>
<body>
<h1>Отчет о системе - $computerName</h1>
<p><b>Дата:</b> $(Get-Date)</p>
<p><b>Время работы системы:</b> $([math]::Round($os.LastBootUpTime.Subtract((Get-Date)).TotalHours * -1, 2)) часов</p>

<h2>ОС</h2>
<table class="os-info">
<tr><td>Название</td><td>$($os.Caption)</td></tr>
<tr><td>Версия</td><td>$($os.Version)</td></tr>
<tr><td>Архитектура</td><td>$($os.OSArchitecture)</td></tr>
<tr><td>Версия BIOS</td><td>$( (Get-CimInstance Win32_BIOS).Name )</td></tr>
<tr><td>Производитель системы</td><td>$( (Get-CimInstance Win32_ComputerSystem).Manufacturer )</td></tr>
<tr><td>Модель системы</td><td>$( (Get-CimInstance Win32_ComputerSystem).Model )</td></tr>
</table>

<h2>Процессор</h2>
<table>
<tr><td>Модель</td><td>$($cpu.Name)</td></tr>
<tr><td>Ядер/Потоков</td><td>$($cpu.NumberOfCores)/$($cpu.NumberOfLogicalProcessors)</td></tr>
<tr><td>Тактовая частота</td><td>$([math]::Round($cpu.MaxClockSpeed/1000, 2)) GHz</td></tr>
<tr><td>Загрузка CPU</td><td>$cpuUsage%</td></tr>
</table>

<h2>Память</h2>
<table>
<tr><td>Всего</td><td>${totalGB}GB</td></tr>
<tr><td>Модули</td><td>$($mem.Count)x$([math]::Round($mem[0].Capacity/1GB))GB $($mem[0].Manufacturer)</td></tr>
<tr><td>Используется</td><td>$([math]::Round(($os.TotalVisibleMemorySize - $os.FreePhysicalMemory)/1MB, 2))GB / ${totalGB}GB ($([math]::Round(($os.TotalVisibleMemorySize - $os.FreePhysicalMemory)/$os.TotalVisibleMemorySize*100, 2))%)</td></tr>
</table>

<h2>Графические процессоры</h2>
<table class="gpu-info">
<tr><th>Модель</th><th>Память</th><th>Драйвер</th><th>Разрешение</th></tr>
"@

foreach ($gpu in $gpus) {
    $gpuMemory = if ($gpu.AdapterRAM -gt 0) { "$([math]::Round($gpu.AdapterRAM/1GB))GB" } else { "N/A" }
    $html += "<tr><td>$($gpu.Name)</td><td>$gpuMemory</td><td>$($gpu.DriverVersion)</td><td>$($gpu.CurrentHorizontalResolution)x$($gpu.CurrentVerticalResolution)</td></tr>"
}

$html += @"
</table>

<h2>Диски</h2>
<table class="disk-info">
<tr><th>Модель</th><th>Размер</th><th>Состояние</th><th>Разделы</th></tr>
"@

foreach ($d in $disks) {
    $healthClass = if ($d.Health -ne "Healthy") {"warn"} else {""}
    $html += "<tr><td>$($d.Model)</td><td>$($d.Size)GB</td><td class='$healthClass'>$($d.Health)</td><td>$($d.Partitions)</td></tr>"
}

$html += @"
</table>

<h2>Сетевые адаптеры</h2>
<table class="network-info">
<tr><th>Имя</th><th>Интерфейс</th><th>Скорость</th><th>MAC</th><th>IP-адрес</th></tr>
"@

foreach ($adapter in $networkAdapters) {
    $html += "<tr><td>$($adapter.Name)</td><td>$($adapter.Interface)</td><td>$($adapter.Speed)</td><td>$($adapter.MAC)</td><td>$($adapter.IP)</td></tr>"
}

$html += @"
</table>

<h2>Дополнительная информация</h2>
<table>
<tr><td>Версия PowerShell</td><td>$($PSVersionTable.PSVersion)</td></tr>
<tr><td>Логические диски</td><td>$( (Get-PSDrive | Where-Object { $_.Provider -like "*FileSystem*" } | ForEach-Object { "$($_.Name) ($([math]::Round($_.Used/1GB, 2))GB/$([math]::Round($_.Free/1GB, 2))GB" })) -join ', ' )</td></tr>
</table>

</body>
</html>
"@

        $html | Out-File "$fullOutputDir\$fileName" -Encoding UTF8
        return "Отчет создан: \\$($env:COMPUTERNAME)\$($fullOutputDir.Replace(':','$'))\$fileName"
    }
    catch {
        return "Ошибка при создании отчета: $_"
    }
}

# Основной цикл обработки компьютеров
foreach ($computer in $computers) {
    Write-Log "Начинаем обработку компьютера: $computer"
    
    try {
        $remoteOutputDir = Join-Path $centralLogsFolder $computer
        Get-RemoteSystemInventory -computerName $computer -outputDir $centralLogsFolder -maxReports $maxReportsPerComputer -credential $cred
    }
    catch {
        Write-Log "Критическая ошибка при обработке компьютера $computer : $_" -level "ERROR"
    }
    
    Write-Log "Завершена обработка компьютера: $computer"
}

Write-Log "Скрипт завершил работу" -level "INFO"

1. Настройка централизованного хранения логов

$centralLogsFolder = "\\сервер\общая_папка\Logs"
$maxReportsPerComputer = 5
$logFile = Join-Path $centralLogsFolder "InventoryScript_$(Get-Date -Format 'yyyyMMdd').log"

Скрипт создаёт единое хранилище отчётов в сетевой папке, что позволяет:

  • Централизованно управлять отчётами

  • Вести детальный лог выполнения

2. Функция логирования

function Write-Log {
    param([string]$message, [string]$level = "INFO")
    $timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
    $logEntry = "[$timestamp][$level] $message"
    Add-Content -Path $logFile -Value $logEntry
    Write-Host $logEntry -ForegroundColor $(if ($level -eq "ERROR") { "Red" } elseif ($level -eq "WARNING") { "Yellow" } else { "White" })
}

Плюсы реализации:

  • Несколько уровней логирования (INFO, WARNING, ERROR)

  • Вывод в консоль и запись в файл (для удобства)

  • Визуальное выделение ошибок (каждой свой цвет, тоже для удобства)

3. Получение списка компьютеров

В скрипте я указал 3 способа получения списка рабочих машин:

# Из Active Directory
$computers = Get-ADComputer -Filter * | Select-Object -ExpandProperty Name

# Из текстового файла
$computers = Get-Content "C:\path\to\computers.txt" | Where-Object { $_ -notmatch '^\s*#' -and $_ -ne '' }

# Заданный список
# $computers = @("COMPUTER1", "COMPUTER2", "COMPUTER3")

В текущей версии активирован способ 2 - чтение из файла. Можно переписать под CSV-файл.

4. Механизм удалённого выполнения

Основная функция Get-RemoteSystemInventory реализует несколько важных особенностей:

Отказоустойчивость:

  • Проверка доступности компьютера перед подключением

  • Автоматическое переключение между PSRemoting и WMI

  • Обработка ошибок

if (-not (Test-Connection -ComputerName $computerName -Count 2 -Quiet)) {
    Write-Log "Компьютер $computerName недоступен по сети" -level "WARNING"
    return
}

Гибкое подключение:

try {
    $session = New-PSSession @sessionParams
} catch {
    Write-Log "Не удалось подключиться через PSRemoting, пробуем WMI" -level "WARNING"
    Invoke-Command -ComputerName $computerName -Credential $credential -ScriptBlock $scriptBlock -ArgumentList $outputDir, $maxReports
}

5. Функция сбора данных (Get-SystemInventory)

Эта функция выполняется на удалённых компьютерах и собирает:

Основные системные данные:

  • Общую инфу о системе

  • Данные об ОС

  • Характеристики процессора

  • Информацию о памяти

  • Данные о видеокартах

  • Состояние дисков

  • Сетевые настройки

  • Дополнительную информацию

Пример обработки дисков:

$disks = Get-Disk | ForEach-Object {
    $partitions = Get-Partition -DiskNumber $_.DiskNumber | ForEach-Object {
        $vol = Get-Volume -Partition $_
        $freeSpacePercent = if ($vol.Size -gt 0) { [math]::Round(($vol.SizeRemaining / $vol.Size) * 100, 2) } else { 0 }
        $freeSpaceClass = if ($freeSpacePercent -lt 10) { "err" } elseif ($freeSpacePercent -lt 20) { "warn" } else { "" }
        "<span class="$freeSpaceClass">$($_.DriveLetter) $([math]::Round($_.Size/1GB))GB ($([math]::Round($vol.SizeRemaining/1GB))GB свободно, $freeSpacePercent%)</span>"
    }
    ...
}

6. Управление отчётами

Скрипт автоматически чистит старые отчёты, оставляя только указанное кол-во:

Get-ChildItem $fullOutputDir -Filter "Inventory_*.html" | 
    Sort-Object CreationTime -Descending | 
    Select-Object -Skip $maxReports | 
    Remove-Item -Force -ErrorAction SilentlyContinue

Как выглядит отчёт:

ОС, процессор, память
ОС, процессор, память
Графические процессоры, диски, сетевые адаптеры, дополнительная информация
Графические процессоры, диски, сетевые адаптеры, дополнительная информация

Практическое применение

Я делал скрипт для формирования понимания о парке машин, коим сейчас владею, но это далеко не весь перечень потенциально применения:

  1. Инвентаризации парка машин - удобный сбор данных о конфигурациях;

  2. Выявления проблем - обнаружение нехватки места на дисках и тд.;;

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

Заключение

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

P.S. Я запустил свою группу в Телеграмм, буду рад видеть всех, кому интересен процесс написания скриптов и автоматизация в мире IT. Также, там можно найти этот и другие скрипты.

Комментарии (7)


  1. M_AJ
    01.07.2025 10:40

    Свои скрипты это конечно прикольно, но вообще, для этого есть и специализированный софт, например OCS Inventory


    1. eternaladm Автор
      01.07.2025 10:40

      Спасибо за комментарий! Я понимаю, что есть реализация через сторонний софт, но в ситуации с закрытой корпоративной сеткой и жесткой политикой УИБ - реализовывать подобные вещи достаточно тяжело. Исхожу из ситуации, адаптируюсь.


      1. NAI
        01.07.2025 10:40

        с закрытой корпоративной сеткой и жесткой политикой УИБ

        Запуск PS-скриптов выглядит тоже как-то не очень безопасно. Ну и это... жесткая ИБ подразумевает инвентаризацию всего и вся -> должен быть софт или журналы с подписями или SCCM -> кто-то просто поленился написать обоснование\сыграть тендер\протащить софт для учета, но разрешил скрипты, ИБ такая ИБ ¯\_(ツ)_/¯


        1. eternaladm Автор
          01.07.2025 10:40

          Спасибо за комментарий! Честно скажу, в работу ИБшников лезть не очень хочу, они тоже какие-то изменения переживают на данный момент. Возможно что-то поменяется в ближайшее время, обязательно вернусь к софту, но пока скрипты) Это и интересно в целом, написать что-то рабочее, интересное и полезное штатными виндовыми средствами.


  1. Xalyf
    01.07.2025 10:40

    Утилита BGInfo позволяет выводить системную информацию на рабочий стол Windows, а также сохранять данные в файлы различных форматов (текстовый, Excel, Access) или базу данных SQL. Ниже приведены примеры командной строки для выполнения bginfo.exe с сохранением информации в разные форматы или базу данных, основанные на документации и возможностях утилиты.

    1. Сохранение информации в текстовый файл

    Для сохранения данных в текстовый файл с разделителями (например, для последующего импорта в Excel) можно использовать параметр сохранения в файл через меню File > Database или указать это в командной строке.

    Пример команды:

    bginfo.exe config.bgi /silent /timer:0 /log:c:\logs\systeminfo.txt
    
    • config.bgi — файл конфигурации, созданный в BGInfo, определяющий, какие данные выводить.

    • /silent — подавляет сообщения об ошибках.

    • /timer:0 — отключает отображение диалогового окна.

    • /log:c:\logs\systeminfo.txt — указывает путь к текстовому файлу для записи данных.

    Результат: Информация о системе (например, имя компьютера, IP-адрес, MAC-адрес) будет записана в текстовый файл systeminfo.txt в папке c:\logs.

    Примечание: Убедитесь, что папка c:\logs существует, иначе команда выдаст ошибку. Текстовый файл будет содержать данные в формате с разделителями (по умолчанию — табуляция), которые можно открыть в Excel.

    2. Сохранение информации в файл Excel (.xls)

    Для записи данных в файл Excel необходимо указать путь к файлу с расширением .xls в настройках BGInfo или через командную строку.

    Пример команды:

    bginfo.exe config.bgi /silent /timer:0 /db:c:\logs\systeminfo.xls
    
    • /db:c:\logs\systeminfo.xls — указывает путь к файлу Excel, куда будут записаны данные.

    Результат: BGInfo создаст или обновит файл systeminfo.xls с системной информацией в формате, пригодном для Excel.

    Примечание: Для работы с Excel-файлами может потребоваться установленный Microsoft Excel или совместимый просмотрщик. Если файл уже существует, BGInfo добавляет новую запись, не перезаписывая старые данные.

    3. Сохранение информации в базу данных Access (.mdb)

    BGInfo поддерживает запись в базу данных Microsoft Access.

    Пример команды:

    bginfo.exe config.bgi /silent /timer:0 /db:c:\logs\systeminfo.mdb
    
    • /db:c:\logs\systeminfo.mdb — указывает путь к файлу базы данных Access.

    Результат: Данные записываются в файл базы данных Access systeminfo.mdb. Если файл не существует, BGInfo создаст его.

    Примечание: Убедитесь, что утилита имеет права на запись в указанную папку. Формат .mdb устаревший, поэтому для современных систем рекомендуется использовать SQL Server или текстовые файлы.

    4. Сохранение информации в базу данных SQL Server

    Для сохранения данных в базу SQL Server необходимо указать строку подключения к базе данных в настройках BGInfo или в командной строке. Это требует предварительной настройки базы данных и учетной записи с правами на запись.

    Пример команды:

    bginfo.exe config.bgi /silent /timer:0 /db:"Provider=SQLOLEDB;Data Source=SQLServerName;Initial Catalog=BGInfoDB;User ID=User;Password=Pass"
    
    • /db:"Provider=SQLOLEDB;Data Source=SQLServerName;Initial Catalog=BGInfoDB;User ID=User;Password=Pass" — строка подключения к SQL Server.

      • SQLServerName — имя сервера SQL.

      • BGInfoDB — имя базы данных.

      • User и Password — учетные данные для доступа к базе.

    Результат: Данные записываются в таблицу (по умолчанию BGInfoTable) в указанной базе SQL Server.

    Настройка базы данных:

    • Создайте базу данных BGInfoDB на SQL Server.

    • Создайте таблицу BGInfoTable с полями, соответствующими данным, которые вы хотите сохранять (например, HostName, IPAddress, MACAddress).

    • Убедитесь, что пользователь, указанный в строке подключения, имеет права на запись в таблицу.

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

    5. Вывод данных без обновления рабочего стола

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

    Пример команды:

    bginfo.exe config.bgi /silent /timer:0 /db:c:\logs\systeminfo.txt /nodesktop
    
    • /nodesktop — отключает обновление фона рабочего стола.

    Результат: Данные записываются в указанный файл (в данном случае systeminfo.txt), но рабочий стол пользователя остается без изменений.

    6. Пример BAT-файла для автоматизации

    Для автоматизации можно создать BAT-файл, который будет запускать BGInfo с нужными параметрами. Например:

    @echo off
    \\server_name\NETLOGON\BGInfo\bginfo.exe \\server_name\NETLOGON\BGInfo\config.bgi /silent /timer:0 /db:c:\logs\systeminfo.txt
    
    • Путь \\server_name\NETLOGON\BGInfo\ указывает на сетевую папку, где хранятся bginfo.exe и файл конфигурации config.bgi.

    • Данные записываются в c:\logs\systeminfo.txt.

    Применение: Поместите этот BAT-файл в автозагрузку или настройте его выполнение через планировщик задач для регулярного обновления данных.

    7. Дополнительные параметры командной строки

    Вот несколько полезных параметров для управления поведением BGInfo:

    • /popup — отображает информацию во всплывающем окне вместо рабочего стола.

    • /taskbar — помещает значок в область уведомлений, а информация отображается при клике на него.

    • /all — применяет изменения для всех пользователей, вошедших в систему (полезно в среде терминальных серверов).

    • /rtf — сохраняет данные в формате RTF (например, /log:c:\logs\systeminfo.rtf).

    Пример с RTF:

    bginfo.exe config.bgi /silent /timer:0 /log:c:\logs\systeminfo.rtf /rtf
    

    Примечание: Убедитесь, что bginfo.exe и файл конфигурации (например, config.bgi) доступны по указанным путям. Для сетевых путей (UNC) может потребоваться настройка прав доступа. Если вы используете BGInfo в доменной сети, рекомендуется настроить выполнение через групповые политики (GPO), как описано в и.


    1. Xalyf
      01.07.2025 10:40

      Утилита BGInfo (Background Information) от Sysinternals собирает и отображает разнообразную системную информацию о компьютере под управлением Windows. Она позволяет выводить данные на рабочий стол, в файлы или базы данных, в зависимости от настроек. Ниже приведен перечень основных категорий и типов информации, которые может собирать и отображать BGInfo, основанный на документации и возможностях утилиты.

      Основные категории системной информации в BGInfo

      BGInfo поддерживает множество встроенных полей (data fields), которые можно настроить через интерфейс программы или файл конфигурации (.bgi). Вот ключевые данные, которые можно вывести:

      1. Общая информация о системе:

        • Computer Name (Имя компьютера): Полное имя компьютера в сети (например, DESKTOP-ABC123).

        • Domain Name (Имя домена): Доменное имя, к которому подключен компьютер (например, company.local).

        • Workgroup (Рабочая группа): Имя рабочей группы, если компьютер не в домене.

        • OS Version (Версия ОС): Версия операционной системы (например, Windows 10 Pro 22H2).

        • Service Pack (Пакет обновлений): Установленный пакет обновлений (если применимо).

        • Build Number (Номер сборки): Номер сборки Windows (например, 19045).

        • System Type (Тип системы): 32-битная или 64-битная архитектура.

        • Boot Time (Время загрузки): Дата и время последней загрузки системы.

        • System Uptime (Время работы системы): Продолжительность работы системы с момента последней загрузки.

      2. Аппаратные характеристики:

        • CPU (Процессор): Модель и характеристики процессора (например, Intel Core i7-8700).

        • Memory (Память): Общий объем оперативной памяти и/или доступная память (например, 16 GB).

        • Free Disk Space (Свободное место на диске): Свободное место на указанных дисках (например, C: 120 GB free).

        • Total Disk Space (Общий объем диска): Общий объем диска (например, C: 512 GB).

        • Physical Disks (Физические диски): Информация о подключенных дисках.

        • Motherboard (Материнская плата): Производитель и модель (если доступно).

        • BIOS Version (Версия BIOS): Информация о версии BIOS или UEFI.

      3. Сетевые параметры:

        • IP Address (IP-адрес): IP-адреса всех сетевых адаптеров (например, 192.168.1.100).

        • MAC Address (MAC-адрес): Физический адрес сетевого адаптера.

        • Subnet Mask (Маска подсети): Маска подсети для каждого адаптера (например, 255.255.255.0).

        • Default Gateway (Шлюз по умолчанию): Адрес шлюза (например, 192.168.1.1).

        • DNS Server (DNS-сервер): Адреса DNS-серверов.

        • DHCP Server (DHCP-сервер): Адрес сервера DHCP, если используется.

        • Network Adapter (Сетевой адаптер): Название и тип адаптера (например, Ethernet, Wi-Fi).

        • Network Speed (Скорость сети): Скорость соединения (например, 1 Gbps).

      4. Информация о пользователе:

        • User Name (Имя пользователя): Имя текущего пользователя (например, john.doe).

        • Logon Domain (Домен входа): Домен, в котором выполнен вход.

        • Logon Server (Сервер входа): Имя сервера, обработавшего вход в систему.

        • Logon Time (Время входа): Время последнего входа пользователя в систему.

      5. Программное обеспечение и лицензии:

        • Installed Applications (Установленные приложения): Список установленных программ (зависит от конфигурации).

        • Product ID (Идентификатор продукта): Идентификатор Windows или другого ПО.

        • License Status (Статус лицензии): Состояние активации Windows (например, Activated).

      6. Дополнительные параметры (настраиваемые поля):

        • Environment Variables (Переменные среды): Любая переменная окружения, например, %PATH% или %TEMP%.

        • Registry Values (Значения реестра): Данные из реестра Windows (например, ключ HKEY_LOCAL_MACHINE\SOFTWARE).

        • WMI Queries (Запросы WMI): Пользовательские запросы к Windows Management Instrumentation (например, для получения специфичных данных, таких как версия драйвера).

        • Custom Fields (Пользовательские поля): Возможность добавления собственных данных через скрипты (VBScript или PowerShell) или текстовые файлы.

        • Time (Время): Текущее системное время или время в определенном часовом поясе.

      7. Дисковые и файловые параметры:

        • Drive Letters (Буквы дисков): Список доступных дисков.

        • File System (Файловая система): Тип файловой системы (например, NTFS, FAT32).

        • Volume Name (Имя тома): Название тома диска.

      8. Информация о безопасности:

        • Windows Update Status (Статус обновлений): Информация о последних обновлениях Windows.

        • Antivirus Status (Статус антивируса): Состояние установленного антивируса (если поддерживается через WMI).

        • Firewall Status (Статус брандмауэра): Состояние брандмауэра Windows.

      Форматы вывода

      Эти данные можно:

      • Отобразить на рабочем столе в виде текста на фоне обоев.

      • Сохранить в файл: текстовый (.txt), Excel (.xls), RTF (.rtf).

      • Экспортировать в базу данных: Microsoft Access (.mdb) или SQL Server.

      • Вывести в консоль или использовать в скриптах.

      Настройка вывода

      • Через GUI: В интерфейсе BGInfo можно выбрать нужные поля, их порядок, шрифт, цвета и расположение.

      • Через командную строку: Используется файл конфигурации (.bgi), где указаны поля для вывода. Пример:

        bginfo.exe config.bgi /timer:0 /silent
        
      • Пользовательские поля: Можно добавить свои данные, используя VBScript, PowerShell или WMI-запросы. Например, запрос WMI для получения версии антивируса:

        SELECT * FROM AntiVirusProduct WHERE displayName LIKE '%Defender%'
        
      • Для получения некоторых данных (например, через WMI) могут потребоваться права администратора.

      • Поля можно комбинировать в файле конфигурации для создания настраиваемых отчетов.

      • Для вывода в базу данных SQL или Access требуется предварительная настройка структуры базы.


  1. Year
    01.07.2025 10:40

    Проходил этим же путем лет десять назад.

    1. Последовательный опрос компьютера за компьютером - это долго и ненадежно. Если один запрос завис из-за кривого WMI, то скрипт не закончится никогда. При этом есть Invoke-Command -AsJob, который позволяет опросить компьютеры параллельно и отработать зависшие запросы.

    2. Архитектурно лучше, когда скрипт запускается на каждой машине через групповые политики или планировщик заданий, собирает всю инвентори в json или csv и кладет в общую папку, из которой админ в любое время может построить вообще любой отчет. Это вот то, что и делает bginfo, но на powershell можно сделать лучше.

    3. Нет необходимости городить html внутри скрипта. В powershell можно управлять форматированием при выводе (пример и дока). Та самая фича, благодаря которой работают Format-List, Format-Table, прочие Format-*. Наверняка же видели, как легко поменять вывод, делая так:
      get-adcomputer -filter * | Format-Table
      get-adcomputer -filter * | Out-GridView
      get-adcomputer -filter * | ConvertTo-HTML