На просторах интернета можно найти большое количество powershell скриптов, получающих ту или иную информацию о системе. Как правило, это небольшие скрипты либо функции, использующие wmi. Для одной рабочей станции свою задачу они выполняют великолепно, но если компьютеров много, то наступают проблемы.
Основной недостаток в том, что сбор информации идет синхронно, скрипт не приступает к следующему компьютеру, пока не отработает на текущем. В результате для поучения информации со всего парка ПК, в лучшем случае, можно прождать очень много времени, в худшем же сценарий может зависнуть и не завершиться никогда.
Мне хотелось сделать какой-то универсальный инструмент. лишенный вышеперечисленного недостатка. Для удобства использования был написан powershell модуль, содержащий на данный момент одну функцию Get-Systeminfo.
На сегодняшний день функция позволяет получать множество различных сведений о системе. По сути, она содержит в себе большую коллекцию скриптов и легко может быть расширена путем добавления новых сценариев.
Install-Module -Name Systeminfo -Scope CurrentUser
Для других версий ссылка на Github
Основные характеристики функции
- Многопоточность
- Можно использовать протоколы DCOM и WSMAN для подключения к удаленному компьютеру
- Работа с конвейером (например, в домене можно запросить список компьютеров, используя командлет Get-Adcomputer с параметром -filter * передав по конвейеру результат его выполнения Get-Systeminfo, мы получим информацию со всех компьютеров домена)
- Легкая масштабируемость
Я не буду рассматривать технические аспекты того, как работает модуль. Вместо этого постараюсь понятно объяснить, как пользоваться и каким образом можно расширить функционал.
Как пользоваться функцией Get-SystemInfo
Работая с командлетом Get-Adcomputer, я обратил внимание на параметр Properties. Он позволял расширить стандартный вывод команды свойствами, которые были перечислены после него. Именно эта концепция была взята за основу. Например, для того чтобы запросить информацию о модели процессора и оперативной памяти, нужно после параметра Properties перечислить через запятую те свойства, которые мы хотим увидеть в результате выполнения.
Для группировки свойств используются switch параметры. Можно использовать совместно несколько switch параметров и параметр Properties
В процессе работы функции создаются две глобальные переменные $Result и $ErrorResult. Первая содержит компьютеры, с которых удалось получить информацию. Вторая содержит копьютеры, на которых произошли ошибки.
Данные переменные удобно использовать после того как функция отработала. Например, используя стандартный командлет Where-Object, можно выбрать из всех результатов те, которые отвечают определенным критериям.
Более подробные сведения и примеры можно получить, выполнив после установки модуля команду Get-Help Get-Systeminfo -Examples
Файл конфигурации
Функция Get-Systeminfo имеет файл конфигурации, находящийся в папке config. Он представляет из себя powershell скрипт, содержащий основные настройки. Наличие данного файла позволят вносить изменения в функцию, не редактируя основной код модуля. Для того чтобы расширить либо убрать ненужный функционал — нужно всего лишь изменить этот файл.
Основные переменные в файле.
$Defaultinfoconfig определяет, какая информация будет получена, когда функция будет запущена без каких-либо параметров. Добавляя или удаляя свойства из массива, можно настраивать какие сведения будут получены.
$Functionconfig содержит хэш таблицу. Где ключом является свойство, которое будет указываться в параметре Properties, а значением строка в стиле параметров powershell. В строке допустимы следующие параметры: Class, Query, Property, Script, FormatList
$ManualNamespace содержит хэш таблицу, где ключ-это класс, а значение- пространство имен, в котором находится класс. Изменения в таблицу нужно вносить в том случае, если нужный для работы класс не принадлежит пространству имен root\cimv2.
$Switchconfig содержит хэш таблицу: ключом является имя switch параметра, а значением-массив свойств.
Как расширить возможности функции
Предположим, что нужно добавить возможность получать наименование ос. Для этого требуется выполнить 4 действия.
- Придумать название, которое будет однозначно характеризовать то, что мы хотим получить. В данном случае назовем OsCaption.
- Внести изменения в блок параметров функции, отредактировав файл Systeminfo.psm1. Изменить нужно [ValidateSet()] для параметра Properties, добавив название, придуманное на первом шаге.
- Изменить файл конфигурации. Так как наименование ос можно получить через wmi обьект класса Win32_OperatingSystem (свойство caption)
Спойлер
нужно добавить в хэш таблицу $Functionconfig строку вида
OsCaption='-Class Win32_OperatingSystem -Property Caption'
- Если powershell запущен, и модуль был загружен: необходимо перезапустить консоль, либо выполнить Remove-Module Systeminfo
Выполнив четыре простых действия, мы получили новый функционал.
Не всегда представляется возможным получить нужные сведения напрямую из объекта wmi. Иногда для получения информации требуется обработать объекты нескольких классов. Для этих случаев необходимо писать скрипт.
Все скрипты модуля хранятся в папке Scripts. Ссылаться на них можно, используя параметр Script в хэш таблице $functionconfig. То есть, если бы в предыдущем примере требовался скрипт и ему для работы были нужны объекты нескольких классов, то строка для хэш таблицы приняла бы следующий вид
OsCaption='-Class Win32_OperatingSystem,Win32_ComputerSystem -Script Scriptfolder\oscaptionscript.ps1’
После параметра Class нужно перечислить, объекты каких классов требуются для работы. В скрипте они будут доступны через переменные с аналогичным названием-в данном примере это $win32_operatingsystem и $win32_computersystem. Кроме этого во всех сценариях есть три служебных переменных-это $Computername, $Protocol и $Credential.
Скрипт для модуля ничем не отличается от обычного, кроме того, что не требуется использовать Get-Wmiobject, так как wmi объекты уже доступны через соответствующую переменную. Для протокола Dcom нужно учитывать, что вся информация должна быть получена через wmi. Не получится использовать командлеты get-process get-services и прочие подобные. Связано это с местом выполнения скриптов. В случае Dcom протокола все скрипты выполняются там, где запущена функция Get-Systeminfio.
Если для подключения используется протокол Wsman, скрипты выполняются на компьютере, с которого получаем информацию, поэтому нет никаких ограничений: можно использовать любые командлеты. Остальные нюансы использования файла конфигурации можно понять, изучив его подробно. Сейчас там находится множество примеров.
Модуль тестировался на второй и пятой версии powershell, но скорее всего будет работать и на всех остальных. Я рекомендую использовать 5 версию, так как там появилась функция авто дополнения, которая значительно облегчает работу.
Комментарии (9)
Naves
08.05.2018 04:45А следующим этапом мы захотим все это сохранять в БД и получим github.com/OCSInventory-NG
SAGSa Автор
08.05.2018 05:01+1Насколько я понял там требуется устанавливать агент. Мое решение не требует установки агента, используются только штатные средства windows. Результаты возвращаемые функцией представляют из себя объекты, поэтому, можно относительно легко, написать простую функцию для сохранения в БД.
neitri
08.05.2018 08:00Как быть если домена нет? Есть около 20 серверов и 30 рабочих станций. Сколько не пытался ни как не получалось через powershell выполнить команды на другом ПК.
slavius
08.05.2018 09:59Я для этого пользую psexec и winaudit.
http://www.parmavex.co.uk/winaudit.html
• No setup
• Save as csv, rtf and html
• Send by e-mail
• Database export
• Command line
• ?0.00
• European Union Public License
• Download[1.2MB] source code
SAGSa Автор
08.05.2018 10:25Модуль может работает без домена.
Нужно проверить следующее:
- Настройки брандмауэра. Он должен пропускать протокол DCOM или WSMAN в зависимости от того какой будете использовать.
- Настройки UAC. Тут два варианта либо выключить совсем (не рекомендую), либо настроить. Подробности можно почитать тут.
- Использовать параметр Credential. Учетная запись, на компьютере с которого собираете информацию, должна обладать правами администратора системы. Для комфортного использования функции на всех компьютерах должна быть заведена админская учетка с одинаковым именем и паролем(пустые пароли недопустимы).
- Если используется протокол WSMAN нужно настроить WinRM.
ZiggiPop
08.05.2018 08:24Я не понял, вы переизобрели платформозависимый Zabbix на powershell?
SAGSa Автор
08.05.2018 09:04Zabbix это хорошая система мониторинга с кучей плюшек. Да действительно там можно получать информацию о системе с компов. Правда для этого нужно его развернуть и настроить. Установить агенты на рабочих станциях на всё это нужно время и квалифицированные специалисты. Мое решение скорее для повседневной работы, нежели для инвентаризации. Не требуется много времени. Достаточно установить модуль и уже в течении минуты можно получить нужные сведения о системе. Кроме этого если чего то модуль не умеет можно быстренько дописать нужный функционал.
little-brother
В заголовке стоило бы наверно упомянуть, что только Windows-машины.
Неужели до сих пор не создали инструмента с GUI, в котором можно проставить галочки и собрать нужную инфу? Я не знаю о чем думала Microsoft, но писать такое
OsCaption='-Class Win32_OperatingSystem ...
по мне кромешный ад. А если надо с счетчиков инфу снять, напр.
Win32_PerfFormattedData_Tcpip_NetworkInterface where packetspersec!=0
то становится еще грустнее (привет
wbemtest.exe
).Хотя наверно можно привыкнуть, со временем.
SAGSa Автор
С точки зрения microsoft это выглядит так
OsCaption='-Class Win32_OperatingSystem… ' это всего лишь строчка из конфига функции.
Сама по себе она работать не будет.