Отчёт инвентаризации Windows Server с помощью PowerShell

- Кратко: пошаговый пример скрипта PowerShell для сбора инвентарных данных серверов из Active Directory и напрямую с узлов (диски, память, сетевые интерфейсы). Используйте AD для динамического списка серверов, CIM/WMI и PS Remoting для сбора данных. Рекомендуемые пороги: 10% или 10 ГБ свободного места для тревоги дисков.
- Что делает: получает список компьютеров из OU, читает свойства AD и запрашивает Win32_LogicalDisk, Win32_PhysicalMemory и Get-NetAdapter на целевых машинах.
Быстрая навигация
- Предварительные требования
- Получение списка серверов
- Какие данные собирать
- Сбор информации с серверов (диски, память, сеть)
- Сборка итогового скрипта
- Рекомендации, варианты и чеклисты
- Критерии приёмки и план восстановления
- Заключение
Введение
PowerShell — инструмент, широко используемый администраторами серверов. Частая задача — собрать инвентарь серверов и получить представление об окружении. В этой статье показан простой, понятный и расширяемый отчёт инвентаризации Windows Server на PowerShell, который удобно адаптировать и автоматизировать.
Предварительные требования
Перед запуском скрипта убедитесь, что у вас есть:
- Рабочая машина Windows 10/11, присоединённая к Active Directory.
- Установленный модуль ActiveDirectory (RSAT).
- Права на чтение учетных записей компьютеров в AD.
- Возможность выполнять удалённые WMI/CIM запросы к целевым узлам.
- PS Remoting (WinRM/PowerShell Remoting) настроен и доступен на целевых серверах.
Важно: если в вашей сети задействованы брандмауэры или политики безопасности, откорректируйте правила для WinRM/CIM.
Получение списка серверов из AD
Чтобы не поддерживать статический список, лучше вытянуть компьютеры из AD. Пример с использованием модуля ActiveDirectory и Get-ADComputer:
Import-Module ActiveDirectory
$OU = 'OU=Servers,DC=domain,DC=local'
$Params = @{
"SearchBase" = $OU
"Filter" = '*'
}
$Servers = Get-ADComputer @ParamsСовет: сохраняйте полный объект AD (а не только имя), чтобы позже иметь доступ к таким атрибутам, как pwdLastSet, lastLogon, DNSHostName и WhenCreated.
Какие данные стоит собирать
Для базового инвентаря полезно разделить поля на группы:
- Значения с сервера:
- Имя хоста сервера
- Свободное место на дисках (по диску)
- Всего оперативной памяти
- Сетевые подключения (интерфейсы, скорости, статусы)
- Значения из AD:
- PasswordLastSet (pwdLastSet)
- LastLogon
- DNSHostName
- Дата создания учетной записи
Эта комбинация даёт хорошую картину: админские метаданные из AD + реальные показатели с машины.
Сбор информации с серверов — подходы и примеры
Мы будем итерировать по списку серверов и для каждого собирать несколько наборов данных. Для удалённых запросов используют CIM (Get-CimInstance) и PS Remoting (Invoke-Command). WMI — реализация CIM в Windows.
Получение свободного места на дисках
Класс: Win32_LogicalDisk. Он возвращает все логические диски и их свободное место. Первичный вывод может быть сложночитаемым, поэтому форматируем результат в удобный объект.
$Disks = Get-CimInstance -ClassName Win32_LogicalDisk
$DisksResult = $Disks | Foreach-Object {
[PSCustomObject]@{
"Drive" = $_.DeviceID
"FreeSpace" = [Math]::Round(($_.FreeSpace / 1GB),2)
}
}
$DisksResultЕсли нужно пометить диски с низким местом, используйте комбинированный порог: менее 10% ОЗУ или меньше 10 ГБ свободного места — сигнал тревоги. Это помогает избегать ложных срабатываний на очень больших лентах хранения.
$Disks = Get-CimInstance -ClassName Win32_LogicalDisk
$DisksResult = $Disks | Foreach-Object {
$FreeSpace = [Math]::Round(($_.FreeSpace / 1GB),2)
$TotalSpace = [Math]::Round(($_.Size / 1GB),2)
If ( ($FreeSpace / $TotalSpace -LT 0.10) -Or $FreeSpace -LT 10 ) {
$LowDiskSpace = $True
} Else {
$LowDiskSpace = $False
}
[PSCustomObject]@{
"Drive" = $_.DeviceID
"FreeSpace" = $FreeSpace
"LowDiskSpace" = $LowDiskSpace
}
}
$DisksResult

Получение объёма памяти
Класс: Win32_PhysicalMemory. Суммируем Capacity по всем модулям памяти и переводим в гигабайты.
(Get-CimInstance -ClassName Win32_PhysicalMemory | Measure-Object -Property Capacity -Sum).Sum / 1GBЭто даёт общее физическое количество ОЗУ у сервера. Для виртуальных машин иногда имеет смысл сверять это с назначенной памятью в гипервизоре.
Получение сетевых подключений
Cmdlet Get-NetAdapter возвращает сетевые адаптеры, но не имеет параметра ComputerName. Поэтому вызываем его через PS Remoting у целевого сервера:
$NetworkConnections = Invoke-Command -ComputerName $_.DnsHostName -ScriptBlock {
Get-NetAdapter -Physical | Select-Object Name, Status, LinkSpeed
}Вывод будет содержать имя интерфейса, его статус и скорость порта. PS Remoting должен быть доступен для этого вызова.

Полный пример: сборка итогового объекта
Ниже — объединённый скрипт, который берет список серверов из AD и для каждого собирает диски, память и сетевые адаптеры, а также сохраняет данные из AD.
Import-Module ActiveDirectory
$OU = 'OU=Servers,DC=domain,DC=local'
$Params = @{
"SearchBase" = $OU
"Filter" = '*'
}
$Servers = Get-ADComputer @Params
$Servers | Foreach-Object {
$Disks = Get-CimInstance -ComputerName $_.DnsHostName -ClassName Win32_LogicalDisk
$DisksResult = $Disks | Foreach-Object {
[PSCustomObject]@{
"Drive" = $_.DeviceID
"FreeSpace" = [Math]::Round(($_.FreeSpace / 1GB),2)
}
}
$NetworkConnections = Invoke-Command -ComputerName $_.DnsHostName -ScriptBlock {
Get-NetAdapter -Physical | Select-Object Name, Status, LinkSpeed
}
[PSCustomObject]@{
"ServerHostName" = $_.Name
"Description" = $_.Description
"FreeDiskSpace" = $DisksResult
"TotalMemory" = ((Get-CimInstance -ComputerName $_.DnsHostName -ClassName Win32_PhysicalMemory | Measure-Object -Property Capacity -Sum).Sum / 1GB)
"NetworkConnections" = $NetworkConnections
"PasswordLastSet" = $_.pwdLastSet
"LastLogon" = $_.lastLogon
"DNSHostName" = $_.DNSHostName
"CreationDate" = $_.WhenCreated
}
}Этот объект удобно экспортировать в CSV/JSON или адаптировать для вывода в HTML-страницу, базу данных или систему мониторинга.
Расширения и альтернативные подходы
- Использовать Export-Csv/ConvertTo-Json для передачи данных в внешние системы.
- Формировать HTML-таблицу с ConvertTo-Html и стилизовать CSS для удобного просмотра в браузере.
- Интеграция: использовать Ansible, SCCM/ConfigMgr, SaltStack или CMDB для централизованного хранения и отображения метаданных.
- Для больших инфраструктур — собирать данные агентом (Prometheus node_exporter, Telegraf) и хранить в TSDB/CMDB.
Когда подходит этот скрипт: небольшие и средние окружения, быстрый аудит перед миграцией или инвентаризация. Когда не подходит: очень крупные среды с тысячами узлов — тут стоит перейти на распределённые агенты и очередь задач.
Практическая методология (мини-SOP)
- Подготовка: проверьте доступы, модуль ActiveDirectory, работу WinRM и политики PS Remoting.
- Тест: запустите скрипт на 1–3 контрольных серверах, проверьте корректность DNSHostName и доступности CIM/PSRemoting.
- Массовый сбор: выполните по OU; сохраняйте вывод в файл и в систему хранения.
- Агрегация: нормализуйте поля, отметьте тревожные состояния (LowDiskSpace).
- Автоматизация: запланируйте задачу Windows Task Scheduler или CI для регулярного запуска.
Чек-листы по ролям
Администратор сервера:
- Убедиться, что WinRM включён и настроен.
- Проверить права чтения AD и корректность OU.
- Тестировать скрипт на тестовом сервере.
Сетевой инженер:
- Проверить, что интерфейсы корректно возвращают LinkSpeed и Status.
- Сверить данные с конфигурацией коммутаторов/VM-сетью.
Аудитор/Архитектор:
- Сверить PasswordLastSet и LastLogon с политиками безопасности.
- Проверить соответствие реальной памяти и заявленной в CMDB.
Диагностика и план восстановления (runbook)
Mermaid-диаграмма для быстрого решения проблем при ошибках сбора:
flowchart TD
A[Начало] --> B{Get-ADComputer вернул результат?}
B -- Да --> C{DNSHostName доступен по сети?}
B -- Нет --> Z[Проверить права AD, SearchBase, фильтр]
C -- Да --> D{PS Remoting отвечает?}
C -- Нет --> Y[Проверить DNS, NetBIOS, имя хоста]
D -- Да --> E{Get-CimInstance/Invoke-Command успешны?}
D -- Нет --> X[Проверить WinRM, фаервол и доверия]
E -- Да --> F[Сохранить запись и перейти к следующему серверу]
E -- Нет --> W[Логировать ошибку и отметить сервер для ручной проверки]Краткие шаги восстановления:
- Если AD-запросы не работают — проверьте учетную запись, права и сеть контроллера домена.
- Если PS Remoting не отвечает — проверьте WinRM, сервисы и брандмауэр на целевой машине.
- Если CIM/WMI возвращает ошибки — перезапустите службу WMI (Windows Management Instrumentation) на целевом сервере.
Критерии приёмки
- Скрипт должен корректно возвращать для 95% тестовых серверов набор полей: ServerHostName, FreeDiskSpace (по дискам), TotalMemory, NetworkConnections, PasswordLastSet.
- Для серверов с недоступным PS Remoting должна быть корректная запись об ошибке и отличительный флаг.
- Выходные данные должны быть в формате CSV/JSON/PSObject и не содержать персональных учетных данных.
Снижение рисков и безопасность
- Не храните учётные данные в скрипте в открытом виде — используйте Managed Service Account или защищённые хранилища (Windows Credential Manager, Azure Key Vault).
- Ограничьте права учётной записи, используемой для опроса: только чтение AD и права на удалённые запросы.
- Логируйте и храните логи в защищённом хранилище.
Шаблон «сниппетов» — быстрый чек-лист кода
- Получение AD-узлов:
$Servers = Get-ADComputer -SearchBase 'OU=Servers,DC=domain,DC=local' -Filter '*'- Проверка памяти:
$memGB = (Get-CimInstance -ComputerName server01 -ClassName Win32_PhysicalMemory | Measure-Object -Property Capacity -Sum).Sum / 1GB- Быстрый экспорт в CSV:
$report | Export-Csv -Path .\server-inventory.csv -NoTypeInformation -Encoding UTF8Полезные советы и шаблоны гибкости
- Разделяйте сбор и агрегацию: сначала собирайте «сырые» данные в JSON-файлы, затем выполняйте отдельный этап агрегации и формирования отчёта.
- Для чувствительных окружений используйте Kerberos/NTLM и убедитесь в корректной конфигурации delegation, если требуется учетная запись.
- Добавьте таймауты и повторные попытки при обращении к сетевым ресурсам.
Заключение
Этот пример показывает базовый, надёжный способ собрать инвентарь серверов с помощью PowerShell, комбинируя данные из Active Directory и прямых запросов к узлам. Скрипт легко расширить: добавить проверки обновлений, версии ОС, установленные роли/фичи или интегрировать в систему мониторинга. Начните с тестового запуска, добавьте обработку ошибок и автоматизируйте выполнение по расписанию для регулярных отчётов.
Важно: инвентаризация — непрерывный процесс. Автоматизация и стандартизация форматов ускоряют аудит, планирование емкости и реагирование на инциденты.
Итоговые рекомендации:
- Тестируйте сначала на ограниченном наборе серверов.
- Используйте пороги 10% или 10 ГБ для определения низкого места на диске.
- Храните результаты в формате, удобном для интеграции (CSV/JSON/HTML).
Похожие материалы
RDP: полный гид по настройке и безопасности
Android как клавиатура и трекпад для Windows
Советы и приёмы для работы с PDF
Calibration в Lightroom Classic: как и когда использовать
Отключить Siri Suggestions на iPhone