Мы всегда использовали сценарий регистрации для обновлений антивирусных баз на рабочих местах нашей организации. Подобные технологии удовлетворяла нас до того момента, пока мы не решили обновить на клиентских компьютерах версию вирус-сканера на более новую. Через несколько минут после включения сценария, мы начали получать звонки от наших пользователей. Некоторые ждали более 5 минут окончания процесса загрузки и получения возможности управления своим компьютером; обнаружение установленных версий по сети параллельно с другими функциями сценария регистрации приводило к тому, что процедура регистрации в системе занимала слишком много времени. Для решения этой проблемы я разделил сценарий на две части. Одна часть копировала новые файлы клиенту на компьютер, другая запускалась в новом режиме на компьютере клиента и устанавливала новые программы. Теперь пользователи не ждут окончания установки новых программ, перед тем как они получают управление своей системой.

Разделение на два этапа

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

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

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

Сценарий регистрации запускается в тот момент, когда пользовательская система подключается к сети и пользователь регистрируется, используя доменное имя. Каждый раз, когда запускается сценарий, он копирует установочные и конфигурационные файлы на локальный диск пользователя. Сценарии также изменяют раздел реестра HKEY_CURRENT_USERSoftwareMicrosoftWindowsCurrent VersionRun для запуска команды regedit. exe следующим образом:

%systemroot%
egedit. exe /s
c:installfilessetrun. reg

Показанный на рисунке 2 Setrun.reg, добавляет новую запись для сценария установки в раздел Run.

Рисунок 2. Setrun. Reg
Windows Registry Editor Version 5.00
 [HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindows
CurrentVersionRun]
"Installer"="%systemroot%system32
cscript.exe C:InstallFilesinstaller.vbs"

Выполнение команды Regedit через сценарий регистрации восстанавливает, либо добавляет параметры в реестр, если пользователь или администратор случайно удалили их. Запуск Regedit с ключом /s гарантирует, что команда будет выполняться в автоматическом режиме (без запросов на подтверждение). См. http://msdn.microsoft.com/library/default.asp?url=/library/en-us/setupapi/setup/run_and_runonce_registry_keys.asp для получения дополнительной информации по разделам Run и RunOnce.

Сценарий регистрации - Шаг1

Первый шаг - это создание сценария регистрации, копирующего установочные файлы из выбранного места на локальный диск. Команда xCopy, показанная в фрагменте B в листинге 1 копирует все файлы и папки, указанные в пути источника, установленного в переменной окружения Remote Install Folder Path на каталог-приемник, путь к которому указан в переменой окружения Local Install Folder Path. Ключ /s разрешает копирование всего дерева, а по ключу /d копируются все файлы. Дополнительную информацию об использовании xCopy можно получить по командет:

xCopy /?

Либо посмотреть Windows Help.

Перенаправление вывода команды xCopy в журнальный файл (install. log) перехватывает все сообщения об успешных и ошибочных операциях. Файл журнала имеет метки времени как показано во фрагменте A листинга 1

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

Сценарий установки. ШАГ 2.

Loginscr только копирует файлы, а сценарий установки Installer.vbs, показанный на листинге 2, устанавливает программные пакеты, скопированные на компьютер во время работы сценария регистрации. Installer устанавливает программы, основываясь на инструкциях из входного текстового файла. который был скопирован на систему вместе с пакетом установки.

Installer начинается с объявления постоянных, определяющих путь к файлу журнала, имя файла журнала, путь к папке с дистрибутивами, имя установочного файла с инструкциями. Эти объявления расположены во фрагменте A в листинге2. Эти постоянные используются вне зависимости от сценария.

После объявления постоянных, сценарий создает экземпляр объекта FileSystemObject из Microsoft Scripting Runtime Library, который используется для открытия и чтения входного текстового файла. Сценарий также создает экземпляр Windows Script Host (WSH) Shell - объекта WScript.Shell, как видно во фрагменте B в листинге 2. WScript.Shell обеспечивает работу метода Run. Метод Run используется далее по ходу сценария.

Метод, обеспечивающий отображение сообщений, использует окно Microsoft Internet Explorer (IE). Установка по умолчанию для IE 4. 0 или более поздних версий устанавливает в систему COM-объект InternetExplorer.Application, который предоставляет необходимые методы свойства и события. Метод Navigate обеспечивает навигацию ресурсов индентифицирующихся URL; свойство Busy возвращает логическое значение Boolean, которое указывает, используется ли объект IE в навигации или в операции загрузки. Вы можете узнать больше об объекте навигации InternetExplorer.Application просмотрев статью http://msdn.microsoft.com/library/default.asp?url=/workshop/browser/webbrowser/reference/objects/internetexplorer.asp.

Код во фрагменте C в листинге 2 вызывает объект IE (сохраненный в oIe). Затем сценарий, используя метод Navigate, создает новое пустое окно Internet Explorer, размещая окно в левом верхнем углу экрана компьютера, устанавливает его размер 400 х 400 пиксел и запрещает вывод панели инструментов и панели состояния. Далее сценарий, используя оператор цикла Do...Loop (далее цикл Do While ), вводит задержку 200 миллисекунд, для того, чтобы объект IE полностью загрузил пустое окно документа. По умолчанию свойство IE Visible (видимость) установлено в False, сценарий устанавливаете его значение в True (1), как показано во фрагменте D в листинге 2, так, чтобы пользователь мог видеть окно.

После создания окна, сценарий может записать в него информацию, используя метод Write. Поскольку этот метод вызывается несколько раз за время выполнения сценария, я выделил его в собственную подпрограмму Doc Write, которая помещена во фрагмент F в листинге 2. Doc Write и другие программы установки, а также их полный код имеются в Web и не представлены в листинге 2. Код фрагмента F выводит на экран сообщение Start of Script execution (начало выполнения сценария). Этот же сигнал записывается в файл журнала.

Код фрагмента E в листинге 2 вызывает подпрограмму CheckAndCreateFolder, которая используя метод объекта FileSystemObject FolderExists, подтверждает, что папка для журналов существует. Если папка отсутствует, подпрограмма создает новую папку с использованием метода CreateFolder FileSystemObject. Заметим, что вы можете использовать эту программу для проверки наличия других папок путем ввода пути к папке в качестве параметра подпрограммы.

Входной файл сценария Installerinput. txt, должен существовать прежде, чем сценарий будет использовать его. Так сценарий вызывает метод FileExists объекта FileSystemObject для проверки наличия файла. Это действие показано во фрагменте G на листинге 2. Затем, если файл существует, сценарий использует цикл Do While для просмотра файла по строкам. Цикл продолжается до конца файла, заданного свойством AtEndOfStream объекта TextStream. Если файл отсутствует, сценарий выводит на экран и записывает журнал сообщения об ошибке File not found и заканчивает свою работу.

Файл Installerinput содержит список программных пакетов, устанавливаемых сценарием Installer. Для каждого пакета файл содержит строку, где через запятую перечисляется соответствующая информация. На рисунке 3 показан пример файла Installerinput. Installer использует метод Split языка VBScript для хранения данных Installerinput в строковом массиве (sRLine).

Рисунок 3. Installerinput.Txt
hotfix1.exe,c:installfilesHotfixes,N,0,true,
Installing Hotfix1. Please wait...,1
cscript.exe installvirusScan.vbs,Server1Share1
vscan7,S,0,true,Upgrading McAfee 
Virus Scan to version 7.0. 
    The system will restart after the installation.
 Do NOT cancel. Thank you for your 
cooperation.,1
regedit.exe /s,c:installfilessetwinlogonmsg.reg,
N,0,true,Setting Winlogon Message. 
Please wait...,0

Элементы массива отсортированы следующим образом

  1. Первый элемент в массиве sRLine - это имя исполняемой программы например, hotfix1. exe.
  2. Второй элемент-это путь к файлу, например. C:installfileshotfixes.
  3. Третий элемент - значение флага, определяющего необходимость перезапуска.
  4. Четвертый элемент - значение, передающееся методу Run для установки стиля командного окна
  5. Пятый элемент - значение true или false для команды Run. Значение true останавливает выполнение сценария до тех пор, пока не закончится выполнение внешней программы, запущенной через команду Run.
  6. Шестой элемент - это сообщение программы установки, которое выводится сценарием на экран пользователя и записывается в журнальный файл.
  7. Последний элемент используется для определения необходимости установки пакета.

Сначала сценарий выполняет команды, проверяет последний элемент массива, как показано во фрагменте H листинга 2. Значение 0 означает что установка не должна выполняться, а значение 1 говорит о том, что команда должна быть запущена.

Сценарий использует метод Run из WScript. Объект Shell, вызываемый в начале работы сценария, запускает команду. Метод Run поддерживает один обязательный параметр strCommand, и два необязательных intWindowStyle and bWaitOnReturn. Параметр strCommand определяет команду, которую необходимо запустить. Параметр intWindowStyle - целое значение integer, определят стиль окна. Параметр bWaitOnReturn - логическое значение, задающее команде Run нужно ли ей ждать окончания выполнения команды перед выполнением следующего оператора сценария. Оператор во фрагменте I на листинге 2 передает эти три параметра методу Run.

Установка программ иногда требует перезагрзки системы после окончания установки. Поэтому, если флаг runRestart установлен в значение S (т. е перезагрузка сценарием), код во фрагменте K в листинге2 вызывает процедуру Shutd, которая выполняет программу shutd. exe (программу из Microsoft Windows 2000 Server Resource Kit, копируемую на рабочую станцию пользователя во время выполнения сценария регистрации). Эта программа инициирует выключение и перезапуск системы. Другим допустимым значением для runRestart есть P, задающая сценарию перезапустить систему средствами установленной программы. Значение N запрещает сценарию перезапуск системы.

Как вы могли заметить, информация о работе сценария выводится в заданный выходной текстовый файл. Например, фрагмент J на листинге 2 сценария записывает информацию команды shutdown в файл журнала перед вызовом функции Shutd. Аналогично, сценарий записывает информацию в журнал от остальных выполняющихся команд. Для записи информации в журнал сценарий вызывает процедуру WriteLog и передает сообщение, которое должно быть записано. Затем передает имя выходного файла (mainlog. txt).

Я часто использую WriteLog в моих сценариях для записи данных в текстовый файл. Если файла не существует, WriteLog открывает его в режиме добавления. В любом случае WriteLog вставляет в этот файл сообщение, переданное процедуре в виде новой строки. Для работы с текстовыми файлами WriteLog использует методы WriteLog FileExists, OpenTextFile, CreateTextFile, WriteLine.

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


Листинг 1. Loginscr.cmd
@Echo Off
Set logfile=C:logsinstall. log
Set RemoteInstallFolderPath=server1share1
Set LocalInstallFolderPath=C:installfiles
Date /t > %logfile%
Time /t >> %logfile%
Echo Copying installation files. Please wait. . . 
XCopy %remoteinstallfolderpath%*. * %localinstallfolderpath%
 /s /q /y /v /i /d >> %logfile%
%systemroot%
egedit. exe /s C:installfilessetrun. reg

Листинг 2. Excerpt from Installer.vbs
On Error Resume Next
Const ForReading = 1, ForWriting = 2, ForAppending = 8
Const LogFolderPath = "c:Logs"
Const LogFileName = "mainlog. txt"
Const InstallFolderPath = "C:installfiles"
Const InstallInputFileName = "InstallerInput. txt"
Set ofs = CreateObject("Scripting. FileSystemObject")
Set oWShell = CreateObject("WScript. Shell")
Set oIe = CreateObject("InternetExplorer. Application")
oIe. Navigate "about:blank" 
oIe. ToolBar = 0
oIe. StatusBar = 0
oIe. Width = 400
oIe. Height = 400
oIe. Left = 0
oIe. Top = 0
Do While (oIe. Busy)
 WScript. Sleep 200
Loop
oIe. Visible = True
CheckAndCreateFolder LogFolderPath
DocWrite "Start of Script execution. " & Now
WriteLog LogFolderPath & "" &
 LogFileName,"Start of Script execution. " & Now
If Not ofs. FileExists(InstallFolderPath & ""
 & InstallInputFileName) Then
 WriteDoc "Fatal Error: Path to the Input file is incorrect
 (" & _
 InstallFolderPath & "" &
 InstallInputFileName & _
 "). Please check the path and run the script again. "
 WriteLog LogFolderPath & "" & LogFileName, _
 "Fatal Error: Path to the Input file is incorrect ("
 & InstallFolderPath & "" _
 & InstallInputFileName & "). Please check the
 path and run the script again. "
 WScript. Quit
End If
Set oIFile = ofs. OpenTextFile(InstallFolderPath &
 "" & _
 InstallInputFileName,ForReading)
If err <> 0 Then WriteLog LogFolderPath &
 "" & LogFileName,err. number & _
 "," & err. description & "," & Now
Do While Not oIfile. AtEndOfStream
 rLine = oIFile. Readline
 sRLine = Split(rLine,",")
 runFile = sRLine(0) ' Sets the executable or script name. 
 runFilePath = sRLine(1) ' Sets the path to the executable. 
 runRestart = sRLine(2) ' p = program, s = script, n = no restart
 runWindowState = sRLine(3) ' Sets the state of the run window. 
 runWait = sRLine(4) ' Specifies whether to wait
 for the execution to complete. 
 runInstallMessage = sRLine(5) ' Sets the installation message. 
 If sRLine(6) = 1 Then
 WriteLog LogFolderPath & "" &
 LogFileName,"Installing " & _
 runInstallMessage & " " & Now
 DocWrite "Installing " & runInstallMessage
 Result = oWShell. Run(runFilePath & ""
 & runFile,runWindowState,runWait)
 WriteLog LogFolderPath & "" &
 LogFileName,"run Result = " & Result
 DocWrite "Installation complete. "
 WriteLog LogFolderPath & "" &
 LogFileName,"Installation complete " & Now
 End If
Loop
If LCase(runRestart) = "s" Then
End if
WriteLog LogFolderPath & "" &
 LogfileName,"End of Script execution. " & Now
Set oIe = nothing
Set ofs = nothing
Set oWShell = nothing