Надёжная установка программ средствами групповых политик без SCCM

Централизованно устанавливать программы в домене Active Directory можно либо средствами групповых политик (Group Policy), либо инструментарием наподобие System Center Configuration Manager. Но SCCM — мероприятие недешёвое, поэтому весомая часть системных администраторов распространяет MSI-пакеты политиками. Однако, установка политиками обладает рядом существенных недостатков:

  1. Если инсталляция не удалась с первого раза, она никогда не будет исполнена до конца. Причины сбоя установки могут быть разными, но политика так или иначе создаст в реестре клиентской машины запись «Объект политики с таким-то номером отработал, дело можно закрыть». Идентификатор объекта вы можете найти в ключе HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Group Policy\AppMgmt. Получается, системе безразлично, нормально ли установилась программа — она регистрирует лишь факт исполнения политики, чтобы потом к этому вопросу больше уже не возвращаться.
  2. Если так случилось, что установленную политикой программу кто-то убрал вручную, она не будет возвращена на место автоматически. Проблема известная, вот где я нашёл объяснение, когда столкнулся с ней впервые: https://social.technet.microsoft.com/Forums/windowsserver/en-US/82f1e144-78a3-4446-8aaf-18843c890cdc/force-reinstall-of-applications-deployed-by-software-gpo-after-uninstall. Причина всё та же, что в пункте номер раз.
  3. Иногда требуется задавать особые условия установки или проверки предварительных условий, которые стандартные политики не поддерживают. Например, при инсталляции Oracle VirtualBox добавить сертификат доверенного издателя:
"%~dp0\cert\VBoxCertUtil.exe" add-trusted-publisher "%~dp0\cert\oracle-vbox.cer"

Для решения этих проблем я написал скрипты распространения и убирания программ. Стандартная схема централизованного распространения может выглядеть так:

 

  1. На одном из контроллеров в шаринге NetLogon создаём папку Deployment, внутри которой размещаем папки всех нужных приложений, например:
    \\DC-Riga.WindowsNT.LV\NetLogon\Deployment\7-Zip
    \\DC-Riga.WindowsNT.LV\NetLogon\Deployment\Skype
    \\DC-Riga.WindowsNT.LV\NetLogon\Deployment\FrontMotion_Firefox
    Такое местоположение удобно тем, что контроллеры реплицируют содержимое папки NetLogon между собой, а путь инсталляции можно назначить в виде доменного имени \\WindowsNT.LV\NetLogon\Deployment; в результате, клиенты выполнят установку с ближайшего контроллера.
  2. Внутри папки конкретного приложения сохраняем скрипты установки и убирания приложения:
    \…\7-ZIP
    \…\7-ZIP\x64\7z920-x64.msi
    \…\7-ZIP\x86\7z920-x86.msi
    \…\7-ZIP\Install_7Zip.bat
    \…\7-ZIP\Uninstall_7Zip.bat
  3. Создаём отдельные объекты групповых политик Applications 7-Zip Install и Applications 7-Zip Uninstall, в которых указываем скрипты в секции Startup Scripts. Политики пристёгиваем к нужному контейнеру в Active Directory (например, к корню домена или только к требуемым департаментам). Можно создать группы безопасности, куда внести учётные записи нужных машин, затем разрешить применять политики только этим группам.

GPO_Deployment

 

Теперь собственно скрипт установки на простом примере 7-Zip:

rem Application Install - 7-Zip
set Package_Name_x86=x86\7z920.msi
set Package_Name_x64=x64\7z920-x64.msi
set MSI_Product_Code_x86={23170F69-40C1-2701-0920-000001000000}
set MSI_Product_Code_x64={23170F69-40C1-2702-0920-000001000000}
set Installation_Parameters=
set Desired_Version=0x9140000
set Detected_Version=None
:Check_if_already_installed_x64_on_x64
REG QUERY HKLM\Software\Microsoft\Windows\CurrentVersion\Uninstall\%MSI_Product_Code_x64%
if not %ErrorLevel%==0 goto Check_x86_on_x86
for /f "tokens=2,*" %%a in ('REG QUERY HKLM\Software\Microsoft\Windows\CurrentVersion\Uninstall\%MSI_Product_Code_x64% /v Version ^| findstr Version') do set Detected_Version=%%b
if /i (%Detected_Version%)==(%Desired_Version%) goto End
goto Install
:Check_if_already_installed_x86_on_x86
REG QUERY HKLM\Software\Microsoft\Windows\CurrentVersion\Uninstall\%MSI_Product_Code_x86%
if not %ErrorLevel%==0 goto Check_x86_on_x64
for /f "tokens=2,*" %%a in ('REG QUERY HKLM\Software\Microsoft\Windows\CurrentVersion\Uninstall\%MSI_Product_Code_x86% /v Version ^| findstr Version') do set Detected_Version=%%b
if /i (%Detected_Version%)==(%Desired_Version%) goto End
goto Install
:Check_if_already_installed_x86_on_x64
REG QUERY HKLM\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\%MSI_Product_Code_x86%
if not %ErrorLevel%==0 goto Install
for /f "tokens=2,*" %%a in ('REG QUERY HKLM\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\%MSI_Product_Code_x86% /v Version ^| findstr Version') do set Detected_Version=%%b
if /i (%Detected_Version%)==(%Desired_Version%) goto End
:Install
if /i exist "C:\Program Files (x86)" goto Install_x64
:Install_x86
xcopy /r /y "%~dp0%Package_Name_x86%" "%Temp%\%Package_Name_x86%*"
msiexec /i "%Temp%\%Package_Name_x86%" %Installation_Parameters% /qn
del /f /q "%Temp%\%Package_Name_x86%"
goto End
:Install_x64
msiexec /i "%~dp0%Package_Name_x64%" %Installation_Parameters% /qn
:End

 

Cкрипт убирания программы:

rem Application Uninstall - 7-Zip
set MSI_Product_Code_x86={23170F69-40C1-2701-0920-000001000000}
set MSI_Product_Code_x64={23170F69-40C1-2702-0920-000001000000}
set Installation_Parameters=/norestart
:Check_x64_on_x64
REG QUERY HKLM\Software\Microsoft\Windows\CurrentVersion\Uninstall\%MSI_Product_Code_x64%
if %ErrorLevel%==0 msiexec /x %MSI_Product_Code_x64% %Installation_Parameters% /qn
:Check_x86_on_x86
REG QUERY HKLM\Software\Microsoft\Windows\CurrentVersion\Uninstall\%MSI_Product_Code_x86%
if %ErrorLevel%==0 msiexec /x %MSI_Product_Code_x86% %Installation_Parameters% /qn
:Check_x86_on_x64
REG QUERY HKLM\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\%MSI_Product_Code_x86%
if %ErrorLevel%==0 msiexec /x %MSI_Product_Code_x86% %Installation_Parameters% /qn
:End

 

Дополнительные замечания:

  1. Скрипт установки требует настройки шести переменных: Package_Name_x86, Package_Name_x64, MSI_Product_Code_x86, MSI_Product_Code_x64, Installation_Parameters, Desired_Version, для каждой программы они уникальны. Коды MSI и версию программы я выясняю отдельно, устанавливая программу вручную на тестовых системах.
  2. Разумеется, инсталляции можно запускать не с контроллеров, а из выделенной точки распространения вида \\DeploymentServer.WindowsNT.LV. Учтите, что компьютеры считывают инсталляционные файлы от лица ComputerName$/SYSTEM — убедитесь, что группы Domain Computers и Domain Controllers имеют разрешения чтения как на Share, так и на NTFS.
  3. В любом случае, убедитесь, что путь к выбранному репозиторию добавлен в «белые списки» программ (Application Whitelisting), иначе установка может отказать и по этой причине.
  4. Команда XCopy в %Temp% нужна только для Windows XP/2003, так как на этих системах MSIExec не умеет инсталлировать с сетевых ресурсов. На более новых системах копировать исходник на локальную машину не нужно, можно выполнять команду msiexec напрямую из %~dp0, как это сделано в 64-разрядном блоке.
  5. Загрузочные скрипты на Windows 8 по умолчанию не работают. Причина: Windows 8 на самом деле не выключается (не выполняет Shutdown) — вместо этого, система всегда пытается выполнить Hybrid Sleep. Как окончательное решение, пришлось просто запретить Hybrid Sleep политиками для всех Windows 8.
  6. Для подсчёта процента компьютеров с успешно установленной программой (Compliance) используйте Group Policy Preferences: http://blog.windowsnt.lv/2014/09/22/srp-compliance-report-russian/
Реклама

4 Responses to Надёжная установка программ средствами групповых политик без SCCM

  1. Vasja Pupkin says:

    задумка хорошая, но со своими нюансами. не всегда проверка на наличие установленной утвержденной в производство версии достаточно, ибо не все программы поддерживают update/downgrade (например java). Google Chrome, так тот вообще использует ветку регистра wow6432 как для 64 так и 32-бит версии. но вопрос в другом: как заставить все скрипты за раз, а не по-одному за перезагрузку?

    • Качеством проверок озаботьтесь самостоятельно. А вот со всеми скриптами — вопрос интересный.
      Я сейчас пытаюсь делать инсталляции с помощью WSUS Package Publisher. Не готов ответить на все вопросы, но уже более-менее получается. Рекомендую.
      Явный плюс — установки обновлений производятся во время работы системы, а не при перезагрузках.

      • equinoxnet says:

        Спасибо за рекомендацию WSUS Package Publisher. С нового года начал развертывать софт при помощи WPP (до этого пытался начинать с LUP, но не пошло). Действительно, удобно тем, что программы ставятся в фоне в заданное время. И не нужно ждать перезагрузку (а пользователи у нас работают посменно, компьютеры перегружаются редко).

      • Ещё через WPP я начал собирать Compliance Reports.

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

Заполните поля или щелкните по значку, чтобы оставить свой комментарий:

Логотип WordPress.com

Для комментария используется ваша учётная запись WordPress.com. Выход / Изменить )

Фотография Twitter

Для комментария используется ваша учётная запись Twitter. Выход / Изменить )

Фотография Facebook

Для комментария используется ваша учётная запись Facebook. Выход / Изменить )

Google+ photo

Для комментария используется ваша учётная запись Google+. Выход / Изменить )

Connecting to %s

%d такие блоггеры, как: