Готовые рецепты – Инвентаризация

Дата выхода: 26 июля 2023 г.

Редактировался: 1 августа 2023 г.

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

Этой статьёй я начинаю цикл коротких постов с готовыми скриптами на PowerShell. На оригинальность они не претендуют, но надеюсь помогут некоторым из читателей решить производственные вопросы.

Примечание

Чтобы скрипт отработал необходимо включить на компьютерах пользователей службу WinRM, сделать это можно двумя способами: с помощью групповых политик или с использование утилиты PSexec (скачивается с официального сайта microsoft). В данном скрипте использовался второй вариант, поскольку предприятие ограничивало использование данной службы.
Данный скрипт актуален тогда когда все сотрудники работают, поскольку если человек не будет залогинен в ПК то информации о том чей он мы не получим.
Утилита quser собирающая данные о залогиненых пользователях, выбор пал на неё из-за того, что только она предоставляет данные о RDP подключениях, что актуально при работе в удалённом формате.

 

Принцип работы скрипта следующий:

  1. Сгружаем информацию о всех ПК из AD ( в моём случае OU-шки Employees);
  2. Начинаем пробегаться по всем ПК с помощью цикла;
  3. Проверяем пингуется ли ПК, если не пингуется то добавляем его имя в отдельных текстовый файл ( NoPingPC.txt );
  4. Если пинг идёт то с помощью встроенной утилиты quser узнаем залогиненого пользователя ( поскольку данные в виде строки, то необходимо отсоединить всю не интересующую нас информацию и оставить только "Имя входа пользователя";
  5. Дальше с помощью WMI объектов узнаём серийный номер ПК, наименование производителя ПК, серийный номер монитора и наименование монитора;
  6. Придаём этому всему читабельный вид;
  7. Сгружаем собранную информацию в отдельные CSV файлы ( inventory_PC.csv и inventory_Monitors.csv);
  8. С помощью Exel делаем удобную таблицу из CSV файлов, после чего можно сверять данные например со SnipeIT.
#Собираю все компьютеры домена в текстовый файл, в моём случае они лежат в OU Employees
#(примечание: можете собрать данные в переменную и работать с ней)
Get-ADComputer -SearchBase "OU=Employees, DC=mydomain, DC=ru" -Filter '*' | Select -Exp Name > .\computers.txt

#Загружаю файл со всеми компьютерами в переменную
$AllComputers = (Get-Content .\computers.txt)

#Объявление переменной для хранения всех ПК
$All_PC_info = @()

#Объявляем переменную для хранения всех мониторов
$All_Monitor_info = @()

#Начинаю пробегаться циклом по каждому компьютеру
ForEach( $item in $AllComputers ){

    #Проверяю пингуется ли ПК 
    if ( ( Test-NetConnection $item -informationlevel quiet ) )
    {

        #Включаю службу WinRM если это вам необходимо установите psexec и раскомментируйте строку
        #psexec \\$item sc start WinRm

        #Получаем информацию о залогиненого пользователя
        [pscustomobject]$pc_user = quser /server $item

        #Вырезаем имя пользователя
        [string]$pc_user = ($pc_user[1].split(" "))[1]

        #Выгружаю из AD информацию о пользователе
        #В AD моей компании данные пользователей хранятся на английском языке, 
        #но в атрибуты extensionattribute11, extensionattribute12, extensionattribute13 мы записывали ФИО сотрудников на русском языке, 
        #по этой причине я их выгружаю
        $norm_user_name = Get-ADUser $pc_user -properties extensionattribute11, extensionattribute12, extensionattribute13

        #Складываем ФИО пользователя на русском языке
        [string]$norm_user_name = $norm_user_name.extensionattribute11 + " " + $norm_user_name.extensionattribute12 + " " + $norm_user_name.extensionattribute13

        #Узнаём информацию о ПК пользователя и записываем данные в переменную 
        $bios_info = Get-CimInstance -ComputerName $item -ClassName win32_bios

        #Узнаём информацию о мониторах и записываем данные в переменную
        $monitors_info = Get-CimInstance -ComputerName $item -ClassName wmiMonitorID -Namespace root\wmi

        #Объявляем переменную для хранения всех имён мониторов пользователя на случай если их несколько у него 
        $all_name_mon = @()

        #Объявляем переменную для хранения всех серийных номеров мониторов пользователя
        $all_serial_mon = @()

        #Циклом пробегаемся по списку мониторов (опять же, т.к. их может быть несколько)
        foreach ( $monitor in $monitors_info ){

            #Объявление переменных для хранения имени и серийного номера монитора
            $mon_name = ''
            $mon_serial = ''

            #Расшифровка имени и серийного номера монитора и запись их в переменные
            $monitor.UserFriendlyName | where { $_ -ne 0 } | foreach { $mon_name += [char]$_ }
            $monitor.SerialNumberID | where { $_ -ne 0 } | foreach { $mon_serial += [char]$_ }

            #Запись имени монитора и серийного номера в общие переменные
            $all_name_mon += $mon_name
            $all_serial_mon += $mon_serial

        }

        #Создание таблицы для хранения информации о пользователе и его мониторах
        #По сути придаём полученной информации более приемлемый вид
        $all_mon = @{

            "Пользователь" = [string]$pc_user; 
            "Наименования" = [string]$all_name_mon;
            "Серийный номер" = [string]$all_serial_mon

        }

        #Запись информации о мониторах конкретного пользователя в переменную со всеми данными
        $All_Monitor_info += [pscustomobject]$all_mon

        #Запись информации о ПК пользователя в переменную со всеми данными ( + преобразование в читаемый вид — таблицу )
        $All_PC_info += $bios_info | select @{ "Name" = "Пользователь"; "expression" = { $pc_user } }, 
        @{ "Name" = "ФИО (если есть)"; "expression" = { [string]$norm_user_name } },
        @{ "Name" = "Имя ПК"; "expression" = { [string]$item } },
        @{ "Name" = "Производитель"; "expression" = { $_.Manufacturer } }, 
        @{ "Name" = "Серийный номер ПК"; "expression" = { $_.SerialNumber } }


        #Отключаю службу WinRM опять же если это вам необходимо раскомментируйте строку ниже
        #psexec \\$item sc stop WinRm

    }
    else
    {

    #Если ПК не пингуется добавляю его в отдельный файл 
    $item | Out-File -FilePath .\NoPingPC.txt -Append

    }

}

#Экспорт данных о всех ПК в CSV с учётом языка и кодировки
$All_PC_info | Export-Csv .\inventory_PC.csv -notype -UseCulture -Encoding UTF8

#Экспорт данных о всех мониторах в CSV с учётом языка и кодировки
$All_Monitor_info | Export-Csv .\inventory_Monitors.csv -notype -UseCulture -Encoding UTF8
microsoft автоматизация рецепты