Как эффективно провести инвентаризацию установленного софта::Журнал СА 12.2005
www.samag.ru
Льготная подписка для студентов      
Поиск   
              
 www.samag.ru    Web  0 товаров , сумма 0 руб.
E-mail
Пароль  
 Запомнить меня
Регистрация | Забыли пароль?
О журнале
Журнал «БИТ»
Подписка
Где купить
Авторам
Рекламодателям
Магазин
Архив номеров
Вакансии
Контакты
   

Jobsora

ЭКСПЕРТНАЯ СЕССИЯ 2019


  Опросы

Какие курсы вы бы выбрали для себя?  

Очные
Онлайновые
Платные
Бесплатные
Я и так все знаю

 Читать далее...

1001 и 1 книга  
28.05.2019г.
Просмотров: 1826
Комментарии: 2
Анализ вредоносных программ

 Читать далее...

28.05.2019г.
Просмотров: 1887
Комментарии: 1
Микросервисы и контейнеры Docker

 Читать далее...

28.05.2019г.
Просмотров: 1446
Комментарии: 0
Django 2 в примерах

 Читать далее...

28.05.2019г.
Просмотров: 1066
Комментарии: 0
Введение в анализ алгоритмов

 Читать далее...

27.03.2019г.
Просмотров: 1636
Комментарии: 1
Arduino Uno и Raspberry Pi 3: от схемотехники к интернету вещей

 Читать далее...

Друзья сайта  

Форум системных администраторов  

sysadmins.ru

 Как эффективно провести инвентаризацию установленного софта

Архив номеров / 2005 / Выпуск №12 (37) / Как эффективно провести инвентаризацию установленного софта

Рубрика: Администрирование /  Продукты и решения   | Дополнительные материалы

АНДРЕЙ БИРЮКОВ

Как эффективно провести инвентаризацию установленного софта

Зачастую сбор информации об установленных на клиентских машинах приложениях является для системных администраторов настоящей пыткой, особенно в крупных сетях. Рассмотрим использование WSH-сценариев и групповых политик Active Directory для этой цели.

Как правило, в сетях большинства организаций у пользователей нет прав на установку приложений, и на все машины «залит» одинаковый образ операционной системы. Однако даже в таких строго построенных сетях рано или поздно возникает необходимость в установке отдельным пользователям программ, которые требуются им для работы. Так, например, бухгалтерам нужны различные конфигурации 1С, а менеджерам нужна определенная система управления проектами и так далее. Или же еще более сложная ситуация: ваша компания объединилась с другой, а у той организации корпоративным стандартом антивируса является, к примеру, Symantec, а в вашей – Trend Micro, и вам необходимо узнать, сколько лицензий того и другого программного продукта необходимо продлить в следующем году. Конечно, идеальным решением во всех описанных выше ситуациях было бы четкое документирование сисадмином каждого запроса на установку программного обеспечения. Однако в реальности все обстоит не так хорошо, и администратору, особенно в крупной сети, необходимо какое-либо программное средство для автоматического сбора информации о приложениях. В данной статье для решения поставленной задачи предлагается сценарий Windows Script Host, который с помощью групповой политики Active Directory будет запускаться на клиентских машинах, собирать в текстовый файл информацию об установленных приложениях и затем сохранять ее на разделяемом сетевом ресурсе.

Теоретическая часть

Как известно, информация об установленных в ОС Windows приложениях хранится в реестре. Точнее, в разделе HKEY_LOCAL_MACHINESoftware. Если зайти в эту ветвь реестра, то можно увидеть подразделы, которые содержат информацию об установленных приложениях, в частности, название каждого подраздела соответствует установленному приложению. Конечно, можно собирать информацию о приложениях отсюда, однако это не самый лучший вариант, так как в этой ветке реестра также содержится много служебной информации, которая может существенно осложнить сбор данных и в конечном итоге замедлить работу системы. Гораздо удобнее воспользоваться веткой HKLMSoftwareMicrosoftWindowsCurrentVersionUninstall. Как парадоксально это ни выглядит, но каждое приложение после установки прописывает свои данные в эту ветку реестра. Причем все данные содержат несколько обязательных полей, например поле DisplayName, с помощью которого мы и будем идентифицировать приложения, установленные в системе. На рабочей машине это может выглядеть, например, вот так (см. рис. 1).

Рисунок 1. Содержимое ветки реестра Uninstall

Рисунок 1. Содержимое ветки реестра Uninstall

Таким образом, для того чтобы собрать информацию об установленных в системе пользовательских приложениях, необходимо обойти значения ветки реестра Uninstall и получить содержимое параметра DisplayName. Этот параметр является обязательным для записей об установленных приложениях данной ветки и содержит значение строкового типа, которое удобно сохранять в текстовом файле. Если параметр ветки Uninstall не содержит поля DisplayName, то значит это не установленное приложение, а какая-то служебная информация, и заносить эти данные в отчет не требуется. Таким вот довольно простым способом можно собрать необходимую нам информацию.

Итак, рассмотрев теоретические аспекты написания данного сценария, перейдем к практической части. Исходный текст сценария, который был взят за основу, можно найти по адресу http://www.computerperformance.co.uk/ezine/ezine63.htm.

Практическая часть

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

Листинг 1. Подключение сетевого диска

On Error Resume Next

Set objNetwork = CreateObject("WScript.Network")

Set CheckDrive = objNetwork.EnumNetworkDrives()

objNetwork.MapNetworkDrive "X:", "\\10.0.1.5\share"

А отключить сетевой диск можно с помощью команды:

Листинг 2. Отключение сетевого диска

WScript.Sleep 3000

objNetwork.RemoveNetworkDrive CheckDrive.Item(0), true

Конечно, если в вашей сети уже используются сетевые диски или после подключения сетевого ресурса вам не нужно отключать его (так как он может использоваться еще для каких либо целей), то вы можете не использовать данные команды и сразу перейти к написанию сценария, описанного ниже.

Ключевым моментом нашего сценария является цикл, обходящий ветку реестра Uninstall:

Листинг 3. Обходим ветку реестра и сохраняем данные в файл

unKeyPath = "Software\Microsoft\Windows\CurrentVersion\Uninstall"

unValueName = ("DisplayName")

objReg.EnumKey HKLM, unKeyPath, arrSubKeys

i=0

For Each Subkey in arrSubKeys

objDictionary2.Add i, unKeyPath & "\"& subkey & (Enter)

i=i+1

Next

………………………

For Each objItem in objDictionary2

strKeyPath = objDictionary2.Item(objItem)

objReg.GetStringValue HKLM ,strKeyPath, unValueName, strValue

'сохраняем нужное значение в файл

objTextFile2.WriteLine (strValue)

If Err Then

objDictionary2.Remove(objItem)

End If

Next

Теперь остается лишь оформить полученные данные должным образом (то есть добавить информацию об имени пользователя, имени компьютера и времени выполнения сценария) и сохранить в файле.

Для получения информации об имени пользователя и названии машины воспользуемся следующими двумя значениями параметров реестра:

Листинг 4. Ветки, содержащие информацию об имени пользователя и имени компьютера

pcName = "SYSTEMCurrentControlSetControlComputerNameActiveComputerName"

pcNameValueName = "ComputerName"

userPath = "SoftwareMicrosoftWindows NTCurrentVersionWinlogon"

userValueName = "DefaultUserName"

В результате работы описанных выше процедур мы получаем текстовый файл, в заголовке которого будут имя пользователя, название, дата и время создания.

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

Листинг 5. Полный текст сценария

' Объявляем константу HKEY_LOCAL_MACHINE

Const HKLM = &H80000002

Const REG_SZ = 1 '

Const ForReading = 1

Const ForWriting = 2

On Error Resume Next

Set objFSO = CreateObject("Scripting.FileSystemObject")

Set objDictionary2 = CreateObject("Scripting.Dictionary")

Dim objNetwork, objShell, CheckDrive

Dim strDriveLetter, strRemotePath, intDrive, bforce

' Данные для сетевого диска

strDriveLetter = UCase("x:" ) ' Имя диска

strRemotePath = "\\10.0.1.5\tmp" ' Сетевой путь

bforce = true

Set objShell = CreateObject("WScript.Shell")

Set objNetwork = CreateObject("WScript.Network")

Set CheckDrive = objNetwork.EnumNetworkDrives()

' А это уже путь, где будет создан файл с информацией о приложениях

strPath = "x:\"

strComputer = "localhost" ' Проверяем локальный компьютер

' Подключаем сетевой диск

objNetwork.MapNetworkDrive strDriveLetter, strRemotePath

' Запускаем процедуру сбора информации

GetInstalledSoftware()

' Отключаем сетевой диск

If CheckDrive.Item(intDrive) <> strDriveLetter  Then objNetwork.RemoveNetworkDrive CheckDrive.Item(0), bforce

Sub GetInstalledSoftware()

On Error Resume next

Set objReg=GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & _

strComputer & "\root\default:StdRegProv")

If Err <> "0" Then

Exit Sub

End If

' Путь к разделу реестра Uninstall, содержащему информацию об установленных компонентах

unKeyPath = "Software\Microsoft\Windows\CurrentVersion\Uninstall"

unValueName = ("DisplayName")

objReg.EnumKey HKLM, unKeyPath, arrSubKeys

i=0

For Each Subkey in arrSubKeys

objDictionary2.Add i, unKeyPath & "\"& subkey & (Enter)

i=i+1

Next

pcName = "SYSTEM\CurrentControlSet\Control\ComputerName\ActiveComputerName\"

pcNameValueName = "ComputerName"

userPath = "Software\Microsoft\Windows NT\CurrentVersion\Winlogon\"

userValueName = "DefaultUserName"

objReg.GetStringValue HKLM,pcName,pcNameValueName,pcValue

objReg.GetStringValue HKLM,userPath,userValueName,userValue

strFileName = UserValue & "_" & "On" & "_" & PCValue & "_"& "Software" _

& year(date()) & right("0" & month(date()),2) _

& right("0" & day(date()),2) & ".txt"

Set objTextFile2 = objFSO.OpenTextFile(strPath & strFileName, ForWriting, True)

objTextFile2.WriteLine(vbCRLF & _

"Current Installed Software " & vbCRLF & Time & vbCRLF & Date _

& vbCRLF & "Software For:" & "" & userValue & vbCRLF & "On System:" _

& "" & pcValue & vbCRLF)

For Each objItem in objDictionary2

strKeyPath = objDictionary2.Item(objItem)

objReg.GetStringValue HKLM ,strKeyPath, unValueName, strValue

objTextFile2.WriteLine (strValue)

If Err Then

objDictionary2.Remove(objItem)

End If

Next

End Sub

wscript.Quit

Сбор урожая

Если в вашей локальной сети менее десяти компьютеров, то запуск описанного выше сценария не составит особого труда. Можно воспользоваться столь любимой всеми системными администраторами программой Remote Admin и удаленно запустить сценарий на каждой клиентской машине. Однако все эти решения требуют от администраторов много ручной работы, а это не слишком хорошо. В оригинальной версии сценария [2] предлагалось использовать следующую процедуру, которая сначала собирает данные о машинах в домене, потом пытается запустить сценарий на каждом из этих компьютеров.

Листинг 6. Запуск сценария на удаленных машинах домена

Set objPCTXTFile = objFSO.OpenTextFile("c:\test.txt", ForWriting, True)

' Получаем информацию о домене

Set objDomain = GetObject("WinNT://" & strDomain)

' Интересует объект компьютеры

objDomain.Filter = Array("Computer")

For Each pcObject In objDomain

    objPCTXTFile.WriteLine pcObject.Name

Next

objPCTXTFile.close

' Читаем компьютеры из созданного файла

Set readPCFile = objFSO.OpenTextFile(strPath & strPCsFile, ForReading)

i = 0

Do Until readPCFile.AtEndOfStream

strNextLine = readPCFile.Readline

objDictionary.Add i, strNextLine

i = i + 1

Loop

readPCFile.Close

' Запускаем процедуру сбора информации на каждом компьютере

For each DomainPC in objDictionary

strComputer = objDictionary.Item(DomainPC)

GetInstalledSoftware()

Next

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

Таким образом мы приходим к выводу, что вариант с одновременным опросом всех машин в сети нас не устраивает. К тому же с помощью такой реализации практически невозможно собрать информацию в сети, которая географически разнесена по разным регионам, когда в одном офисе рабочий день только начинается, а в другом – уже заканчивается.

Возможен еще другой вариант для запуска нашего сценария на пользовательских машинах – это Logon Script. Для доступа к нему необходимо в свойствах пользователя (или нескольких выбранных пользователей) в закладке Profile указать путь к файлу сценария (см. рис. 2).

Рисунок 2. Указываем Logon Script

Тогда наш сценарий будет выполняться при входе пользователя в домен. Такое решение уже более универсально, чем предыдущее, но все равно от администратора требуется вручную выделить всех пользователей, у которых должен быть запущен сценарий. А если таких пользователей сотни? К тому же если у нас несколько пользователей заходят на один и тот же компьютер, то мы получим несколько одинаковых файлов отчета, различающихся только именем пользователя. Думаю, разбирать потом все это будет не слишком удобно. Так что такой вариант для больших сетей тоже не подходит.

Очевидно, что для подобных случаев лучше всего выполнять сценарии на клиенте с помощью групповых политик Active Directory. Групповую политику можно рассматривать как набор правил для управления пользователями и компьютерами. Групповую политику разрешается применять в нескольких доменах и в подгруппах внутри домена или индивидуальных системах. Параметры групповой политики хранятся в объекте групповой политики (Group policy Object, GPO). К одному и тому же домену или подразделению можно применять несколько объектов GPO. Подробнее о взаимодействии политик, свойствах Block Inheritance и No Override можно прочитать в [1].

Итак, создадим свою групповую политику и используем ее для автоматизации развертывания нашего сценария. Для этого зайдем локально или удаленно на контроллер домена «Administrative Tools  Active Directory Users and Computers  Домен». В меню «Action  New  Organization Unit» (введем название), затем в свойствах созданной организационной единицы закладка «Group Policy», нажимаем «New», указываем имя новой политики и затем, нажав «Edit», попадаем в редактор объектов GPO. Для решения поставленной задачи развертывания сценария на машинах пользователей нам удобнее будет использовать раздел «Computer Management», конечно, если мы используем «Computer Management», ничего страшного не произойдет, но, как и в случае с Logon Script, если за компьютером работают несколько пользователей, то мы рискуем получить несколько одинаковых файлов отчетов, которые будут отличаться только именем пользователя в заголовке. В разделе «Computer Management» заходим в «Windows Settings», далее «Scripts» (см. рис. 3).

Рисунок 3. Объекты групповой политики

Рисунок 3. Объекты групповой политики

Здесь возможны два варианта «Startup» и «Shutdown». Логичнее будет использовать наш сценарий при запуске пользовательской машины.

Нажимаем «Add» и добавляем файл сценария без параметров. Все, теперь наш сценарий будет выполнен при следующем запуске компьютера. В случае если необходимо использовать раздел «User Configuration», соответствующие разделы будут «Windows Settings» и «Scripts (Logon/Logoff)». Теперь остается только перетащить машины, к которым будет применена данная групповая политика в созданную нами Organization Unit.

Следует сказать несколько слов о нагрузке на сеть, которую создаст наш сценарий в тот момент, когда пользователи, придя утром на работу, начнут массово входить в сеть. Что касается времени выполнения сценария и его нагрузки на компьютер пользователя, то на средней машине с 2030 установленными приложениями (хотя в тех организациях, где люди прежде всего работают, таких приложений, как правило, меньше) время работы сценария будет, не более трех секунд. По поводу трафика стоит отметить, что на той же машине с 30 установленными приложениями файл отчета займет около 3 килобайт, так что даже в моменты пиковой нагрузки речь может идти лишь о нескольких сотнях килобайт трафика.

Подведение итогов

Итак, мы собрали все необходимые нам сведения об установленных на пользовательских машинах приложениях и сохранили их в виде отдельных файлов на сервере. Но такой способ хранения полученной информации не слишком удобен, к тому же мы не решили одну из задач, поставленных в начале статьи, – сбор информации о количестве установленных приложений, необходимой для осуществления лицензирования. Таким образом, нам требуется, во-первых, собрать все данные в единый файл и, во-вторых, просуммировать все одинаковые приложения. Обе эти задачи мы решим с помощью Microsoft Excel. Напишем WSH-сценарий, который необходимо будет разместить в том же каталоге, что и файлы, которые мы получили. После запуска данный сценарий поочередно открывает каждый из файлов каталога и экспортирует данные о приложениях в таблицу Excel, затем производится сбор сведений о количестве установок, которые также экспортируются в Excel. В результате работы сценария мы получаем книгу Excel, содержащую два листа: На первом таблица, состоящая из двух столбцов, – имя компьютера и наименование приложений.

На втором листе список приложений и количество установок каждого из них.

Рисунок 4. Таблица Excel с результатами

Рисунок 4. Таблица Excel с результатами

Далее приводится фрагмент сценария, реализующего все эти действия.

Листинг 7. Создание документа Excel c результатами

…………….

Set s = oE.Sheets(1)     ' Лист 1

s.Name = "Список"      

Set s1 = oE.Sheets(2)    ' Лист 2

s1.Name = "Сумма"      

s.Rows(1).RowHeight = 2 * s.StandardHeight

s.Cells(1,1) = "Список установленных приложений"

s.Cells(2,1) = "Имя компьютера"    

s.Cells(2,2) = "Приложения"        

s.Columns("A:B").Columns.AutoFit

With s.Range("A1:B1") 

  .MergeCells = True

  .VerticalAlignment = xlCenter

  .HorizontalAlignment = xlCenter

  .Font.Size=14

End With

s1.Rows(1).RowHeight = 2 * s1.StandardHeight

s1.Cells(1,1) = "Количество установленных приложений"

s1.Cells(2,1) = "Приложение"    

s1.Cells(2,2) = "Всего установок"      

s1.Columns("A:B").Columns.AutoFit

With s1.Range("A1:B1")

  .MergeCells = True

  .VerticalAlignment = xlCenter

  .HorizontalAlignment = xlCenter

  .Font.Size=14

End With

Set objFSO = CreateObject("Scripting.FileSystemObject")

Set fso = CreateObject("Scripting.FileSystemObject")

' Получаем сведения о файлах, находящихся в данной папке

Set fld = fso.GetFolder(".")

Set objTextFile2 = objFSO.OpenTextFile("c:\temp\tmp", ForWriting, True)

For Each fi In fld.Files

If fi.name<>"excel.vbs" AND fi.name<>"result.xls" Then

' Файл сценария и файл отчета не открывать

Set readPCFile = objFSO.OpenTextFile(fi, ForReading)

i = 0

s.Cells(n, 1) = fi.name ' Имя файла – это имя компьютера

Do Until readPCFile.AtEndOfStream

strNextLine = readPCFile.Readline

  i = i + 1

  ' Первые 6 строк в файлах отчетах – это шапка,

  ' экспортировать не нужно

  If i>6 Then 

    s.Cells(n, 2) = strNextLine

   objTextFile2.WriteLine (strNextLine)

    n = n + 1

    End If

  Loop

 readPCFile.Close

End If

Next

objTextFile2.close

f=3

Set objTextFile2 = objFSO.OpenTextFile("c:\temp\tmp", ForReading)

Do Until ObjTextFile2.AtEndOfStream

 strNextLine = objTextFile2.Readline

 ' ищем вхождения имени приложения

 Set fc = s1.Columns("A").Find(strNextLine)

 If  fc Is Nothing  Then ' не нашли, тогда добавляем

  s1.Cells(f,1)=strNextLine

  Set fc = s.Columns("B").Find(strNextLine)

   If Not fc Is Nothing  Then

    count=0

   With s.Columns("B")

    Set c = .Find(strNextLine)

    If Not c Is Nothing Then

        firstAddress = c.Address

        Do

           ' считаем количество установок

           count=count+1

            Set c = .FindNext(c)

        Loop While Not c Is Nothing And c.Address <> firstAddress

    End If

End With

s1.Cells(f,2)=Count ' сохраняем количество установок

 End If

f=f+1

End If

Loop

Теперь поставленная перед нами задача по сбору сведений об установленных на клиентских машинах приложениях решена полностью. Мы получили таблицу Excel, которая содержит сведения о том, какие приложения установлены на каждой конкретной машине, а также сведения о том, сколько установок того или иного приложения имеется в сети. Лучше всего выполнять описанные выше сценарии регулярно, с частотой один раз в месяц, для того чтобы всегда иметь под рукой актуальную информацию об используемом программном обеспечении.

Литература:

  1. Windows Server 2003. Справочник администратора.
  2. http://www.computerperformance.co.uk – англоязычный сайт, содержащий множество примеров WSH сценариев, с комментариями.

Комментарии отсутствуют

Добавить комментарий

Комментарии могут оставлять только зарегистрированные пользователи

               Copyright © Системный администратор

Яндекс.Метрика
Tel.: (499) 277-12-41
Fax: (499) 277-12-45
E-mail: sa@samag.ru