Как стать автором
Обновить

Инвентаризация компьютеров в домене. Лень-двигатель прогресса

PowerShell *
Из песочницы
Всех приветствую.
Недавно начальство попросило меня подумать над вопросом о сборе информации о комплектации компьютеров у нас в домене. Сначала просьба была только на счет процессоров памяти и жестких дисков. Первая мысль — хождение по отделам и просьба освободить компьютер на минутку. В случае с 1 компьютером не сложно, но если их 1500. Мысли были направленны в сторону PowerShell.

Для начала надо было извлечь список всех компьютеров в домене. В данном примере мой домен Test.lan. Импортируем весь этот список в файл AllComputers.csv.
Для этого не забываем добавить модуль АД для PS. У меня на рабочем месте он прописан в профиле, и вам советую сделать тоже самое:

import-module activedirectory
get-ADcomputer -Filter * |
Where-Object {$a=$_.name; $_.DistinguishedName -ne "CN=$a,OU=Disable,DC=Test,DC=lan"} |
Sort-Object name | Select-Object name | Export-csv C:\Invent\AllComputers.csv -NoTypeInformation


Здесь надо пояснить, что у меня в домене есть папка Disable, где располагаются учетные записи всех отключенных компьютеров. Если они отключены, то какой смысл к ним стучаться. По этому эту папку мы исключаем из поиска.

Всем понятно, что далеко не все компьютеры, которые находятся в домене, включены, работают или вообще имеют место быть. По этому перед тем, как перейти к проверке, мы проверяем связь с ним. Конечно можно этого не делать, если у вас 100 компьютеров. А если у вас 2000 компьютеров, потеря времени при количестве выключенных компьютеров порядка 800 съест у вас не мало времени. Так же стоит сразу вспомнить компьютеры, к которым у нас нет доступа. Так же смысла стучаться в их дверь нет.

import-csv c:\Invent\AllComputers.csv | foreach {
$a=$_.name
if ((Test-connection $a -count 2 -quiet) -eq "True")
{
if ((Get-WmiObject -computername $a Win32_OperatingSystem) -eq $null)
{


Многие могут возразить:
«Для чего такие сложности? Зачем сначала делать список а потом импортировать его. Не легче ли сразу?»
Согласен, легче. Но иметь перед глазами список компьютеров, согласитесь, приятно. К тому же, список пронумерован. И Вы всегда знаете сколько у вас компьютеров в АД.

Для теста соединения выбрал cmdlet Test-connection с параметром -quiet, дабы нам не выдавались строчки с разной информацией, а просто выдавался ответ: True or False. При чем мы сокращаем количество запросов с 2 до 4.
Если мы постучимся к компьютеру с WMI запросом, а прав на такое действие у нас нет, получим кучу строчек красного цвета с ошибками. Так что сразу отфильтровываем такие компьютеры пробным WMI запросом

Любую информацию (наверное, почти любую) можно узнать, если залезть в WMI объекты, а PS позволяет это делать просто на ура. Так что я сразу углубился в поиски нужных WMI объектов.
Здесь можно поглядеть все классы с их атрибутами.
Убедившись, что компьютер в сети, что доступ у нас к нему есть, смотрим его внутренности:

Write-Host "Проверка компьютера " -ForeGroundColor Green $a
"Компьютер" | out-file c:\Invent\Comp\$a.txt
Get-WmiObject -computername $a Win32_OperatingSystem |
select-object csname, caption, Serialnumber, csdVersion |
ft @{Label="Сетевое имя"; Expression={$_.CSname}},
@{label="Наименование"; Expression={$_.caption}},
@{label="Версия"; Expression={$_.csdVersion}},
@{label="Серийный номер"; Expression={$_.SerialNumber}} -auto -wrap |
out-file c:\Invent\Comp\$a.txt -append
Get-WmiObject -computername $a Win32_ComputerSystemProduct | select-object UUID |
ft UUID -autosize | out-file c:\Invent\Comp\$a.txt -append
"Процессор" | out-file c:\Invent\Comp\$a.txt -append
Get-WmiObject -computername $a Win32_Processor | select-object name, SocketDesignation, Description |
ft @{label="Имя"; Expression={$_.name}},
@{label="Разъем"; Expression={$_.SocketDesignation}},
@{label="Описание"; Expression={$_.Description}} -auto -wrap | out-file c:\Invent\Comp\$a.txt -append
"Материнская плата" | out-file c:\Invent\Comp\$a.txt -append
Get-WmiObject -computername $a Win32_BaseBoard | select-object Manufacturer, Product, SerialNumber |
ft @{label="Производитель"; Expression={$_.manufacturer}},
@{label="Модель"; Expression={$_.Product}},
@{label="Серийный номер"; Expression={$_.SerialNumber}} -auto -wrap |
out-file c:\Invent\Comp\$a.txt -append
"Жесткие диски" | out-file c:\Invent\Comp\$a.txt -append
Get-WmiObject -computername $a Win32_DiskDrive | select-object Model, Partitions, Size, interfacetype |
ft @{Label="Модель"; Expression={$_.Model}},
@{Label="Количество разделов"; Expression={$_.Partitions}},
@{Label="Размер (гб)"; Expression={($_.Size/1GB).tostring("F00")}},
@{Label="Интерфейс"; Expression={$_.interfaceType}} -auto -wrap |
out-file c:\Invent\Comp\$a.txt -append
"Логические диски" | out-file c:\Invent\Comp\$a.txt -append
Get-WmiObject -computername $a Win32_LogicalDisk -Filter "DriveType=3" | select-object DeviceID, FileSystem, Size, FreeSpace |
ft @{Label="Наименование"; Expression={$_.DeviceID}},
@{Label="Файловая система"; Expression={$_.FileSystem}},
@{Label="Размер (гб)"; Expression={($_.Size/1GB).tostring("F00")}},
@{Label="Свободное место (гб)"; Expression={($_.FreeSpace/1GB).tostring("F00")}} -auto -wrap |
out-file c:\Invent\Comp\$a.txt -append
"Оперативная память" | out-file c:\Invent\Comp\$a.txt -append
Get-WmiObject -computername $a Win32_Physicalmemory | Select-Object capacity, DeviceLocator |
ft @{Label="Размер (мб)"; Expression={($_.capacity/1MB).tostring("F00")}},
@{Label="Расположение"; Expression={$_.DeviceLocator}} -auto -wrap |
out-file c:\Invent\Comp\$a.txt -append
"Видеокарта" | out-file c:\Invent\Comp\$a.txt -append
Get-WmiObject -computername $a Win32_videoController |
Select-Object name, AdapterRAM, VideoProcessor |
ft @{Label="Наименование"; Expression={$_.name}},
@{Label="Объем памяти (мб)"; Expression={($_.AdapterRAM/1MB).tostring("F00")}},
@{Label="Видеопроцессор"; Expression={$_.VideoProcessor}} -auto -wrap |
out-file c:\Invent\Comp\$a.txt -append
"Сетевая карта" | out-file c:\Invent\Comp\$a.txt -append
$OS=Get-WmiObject -computername $a Win32_OperatingSystem | foreach {$_.caption}
if ($OS -eq "Microsoft Windows 2000 Professional")
{
Get-WmiObject -computername $a Win32_NetworkAdapterConfiguration -Filter "DHCPEnabled=True" |
Select-Object caption,MACaddress |
ft @{Label="Наименование"; Expression={$_.caption}},
@{Label="MAC адрес"; Expression={$_.MACAddress}} -auto -wrap |
out-file c:\Invent\Comp\$a.txt -append
}
else
{
Get-WmiObject -computername $a Win32_NetworkAdapter -Filter "NetConnectionStatus>0" |
Select-Object name, AdapterType, MACAddress |
ft @{Label="Наименование"; Expression={$_.name}},
@{Label="MAC адрес"; Expression={$_.MACAddress}},
@{Label="Тип"; Expression={$_.AdapterType}} -auto -wrap |
out-file c:\Invent\Comp\$a.txt -append
}
}


Вся информация о компьютере падает в текстовый файл.
Здесь стоит остановить внимание на 2 моментах.
Во-первых, строчку Write-Host "Проверка компьютера " -ForeGroundColor Green $a я делал исключительно для себя, ибо приятно знать чем занимается в данный момент PowerShell.
Во-вторых, для чего мы перед проверкой сетевой карты проверяем ОС.
К сожалению, Windows 2000 не отвечает на запрос Win32_NetworkAdapter, по этому к ней мы применяем запрос Win32_NetworkAdapterConfiguration. Почему не оставить только последний? Можно оставить, но Win32_NetworkAdapter выдает такой атрибут, как Name, когда в его аналоге только Caption. Мелочь, а приятно.
Так же можете видеть, что при проверки сетевой карты, мы проверяем ее на работоспособность, иначе мы получим список еще из нескольких карт, которые в данный момент Вас не интересуют. Вам это надо?

Вот в принципе и все.
Скрипт можно доработать до своих потребностей.
Так что теперь начальство вряд ли напугает вас инвентаризацией компьютеров.
Теги:
Хабы:
Всего голосов 45: ↑35 и ↓10 +25
Просмотры 84K
Комментарии Комментарии 19