Chocolatey + PowerShell: как развернуть софт на 100 ПК за час

от автора

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

Но есть способ лучше — автоматизация через Chocolatey и PowerShell. В этой статье разберём:

  1. Как развернуть ПО на всех машинах за кратчайший срок;

  2. Как создать собственные пакеты и управлять ими;

  3. Как внедрить данное решение в вашу организацию.

Если вы системный администратор, DevOps, ИТ-инженер или специалист ТП — постараюсь помочь сэкономить вам десятки часов рутинной работы.

Автоматизация установки ПО в корпоративной сети

Итак, основная проблема. Недавно моя организация закупила партию из 100 новых машин, которые требуют установку набора ПО в зависимости от отдела (бухгалтерия, юристы и тд.). Решать задачу вручную слишком долго, поэтому я выбрал Chocolatey для экономии времени, о котором уже был наслышан от коллеги.

Подводные камни:

  • Корпоративная сеть закрыта, поэтому нет доступа к официальному репозиторию Chocolatey.

  • Загрузка пакетов с мировой паутины запрещена политикой безопасности.

Исходя из этого, решение напрашивается само: развёртывание локального репозитория Chocolatey. Далее постараюсь расписать процесс максимально подробно. Приступим:

Подготовка инфраструктуры

Для реализации потребуется:

  1. Локальный сервер или общая сетевая папка для хранения пакетов.

  2. PowerShell 5+ с правами администратора.

  3. Пакеты .nupkg (в моём случае — собранные вручную).

Варианты локального репозитория:

  1. NuGet.Server — самый простой вариант для Windows.

  2. Nexus Repository — гибкое решение для больших сетей.

  3. Общая сетевая папка — быстрый и простой вариант, но со своими минусами.

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

  • Низкая производительность при массовой установке (поэтому я буду устанавливать ПО, разбив установку на группы по 20-25 машин).

  • Отсутствие контроля версий как в полноценных репозиториях.

Начнем с установки Chocolatey в закрытой корпоративной сети. Для начала нам нужно скачать установочный файл (chocolatey.2.4.3.nupkg) с официального сайта Chocolatey. Далее выполняем перечень команд:

# Переходим в папку с .nupkg cd "C:\Users\Admin\Desktop"  # Распоковываем .nupkg как архив  Rename-Item -Path "chocolatey.2.4.3.nupkg" -NewName "chocolatey.2.4.3.zip" Expand-Archive -Path "chocolatey.2.4.3.zip" -DestinationPath "C:\ChocoInstall" -Force  # Запускаем установку Set-ExecutionPolicy Bypass -Scope Process -Force  & "C:\ChocoInstall\tools\chocolateyInstall.ps1"  # Проверяем корректность установки choco --version 

Создание собственного пакета для распространения

Перед созданием пакета потребуется:

  • Установленный Chocolatey на машине разработчика;

  • Доступ к установочным файлам в сетевой папке;

  • Права администратора на машине, где создаём пакет;

  • Текстовый редактор для изменения файлов пакета (VS Code, Notepad++, Блокнот).

Если все требования соблюдены — приступим к созданию:

  • Генерируем нашу заготовку .nuspec:

choco new buh

Команда создаст шаблон в папке buh (данный пакет мы направим на машины бухгалтеров):

Пример созданного командой шаблона

Пример созданного командой шаблона
  • Редактируем buh.nuspec в текстовом редакторе:

<?xml version="1.0" encoding="utf-8"?> <package xmlns="http://schemas.microsoft.com/packaging/2015/06/nuspec.xsd">   <metadata>     <id>buh-software</id>     <version>1.0.0</version>     <title>ПО для бухгалтерии</title>     <authors>Ваша организация</authors>     <description>Пакет стандартного ПО для отдела бухгалтерии</description>     <tags>бухгалтерия 1с контур office</tags>   </metadata>   <files>     <file src="tools\**" target="tools\" />   </files> </package>
  • Редактируем chocolateyinstall.ps1:

# Политика обработки ошибок: выполняет остановку скрипта при любой ошибке $ErrorActionPreference = 'Stop'   # Параметры установки $installers = @(     @{ Name = '1C'; Path = "\\IT\software\buh\1C\setup.exe"; Args = "/S"; Shortcut = "C:\Program Files\1C\1CEStart.exe" },     @{ Name = 'KonturExtern'; Path = "\\IT\software\buh\KonturExtern\install.msi"; Args = "/i `"$($_.Path)`" /qn"; Process = "msiexec.exe" },     @{ Name = 'BankClient'; Path = "\\IT\software\buh\BankClient\setup.exe"; Args = "/S" },     @{ Name = 'Office'; Path = "\\IT\software\buh\Office\setup.exe"; Args = "/configure configuration.xml" } )  # Установка всех программ foreach ($app in $installers) {     try {         $process = Start-Process -FilePath ($app.Process ?? $app.Path) -ArgumentList $app.Args -Wait -PassThru         if ($process.ExitCode -ne 0) { throw "Exit code $($process.ExitCode)" }         Write-Host "$($app.Name) установлен успешно" -ForegroundColor Green     }     catch {         Write-Warning "Ошибка установки $($app.Name): $_"     } }  # Создание ярлыка (у меня только для 1С по просьбе бухгалтерии) if (Test-Path $installers[0].Shortcut) {     $WshShell = New-Object -ComObject WScript.Shell     $Shortcut = $WshShell.CreateShortcut("$env:Public\Desktop\1C Предприятие.lnk")     $Shortcut.TargetPath = $installers[0].Shortcut     $Shortcut.Save() }
  1. Собираем готовый пакет:

choco pack

Возможно потребуется использование:

cd C:\Users\Admin\Desktop\buh # После выполнения команды повторяем 'choco pack'

Наш пакет в расширении .nupkg готов, копируем в сетевую папку и проверяем работоспособность пакета на тестовой машине:

choco install buh-software -y --source="';\\IT\Software\choco'" --force

Возможные проблемы и их решения

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

Ошибки доступа к общей папке: скрипт выдаёт ошибку «Access denied» или «Network path not found».

  • Необходимо проверить права УЗ, с которой выполняется скрипт. У неё должны быть права на чтение/запись;

  • Возможно потребуется добавить исключение в брандмауэр:

New-NetFirewallRUle -DisplayName "Allow SMB for Chocolatey" -Direction Inbound -Protocol TCP -LocalPort 445 -Action Allow

Долгая установка на некоторых машинах: логи показывают таймаут или скрипт вовсе зависает на отдельных машинах.

  1. Сократить список до 15-20 машин (пример с разбивкой указан ниже);

  2. Добавить -ThrottleLimit 10 в Invoke-Command чтобы ограничить параллельные сессии.

Развёртывание ПО на машинах

После подготовки пакетов необходимо развернуть ПО на всех машинах. Для себя выбрал установку через PowerShell Remoting, но есть и альтернативный вариант через GPO.

Альтернативный вариант через GPO
  1. Создание нового GPO;

  2. Настройка задания (обязательно установить галку на «run with higest privileges»);

  3. Добавить триггер «at startup» (или по расписанию, если вам удобнее);

  4. Действия:

  • Действие: start a program

  • Программа: powershell.exe

  • Аргументы:

-NoProfile -ExecutionPolicy Bypass -Command "choco install buh-software -y --source='\IT\Software\choco' --cache-location='C:\Windows\Temp\choco'"
  1. Доп. параметры:

  • Включаем опцию «run task as soon as possible after a scheduled start is missed»

  • Устанавливаем «stop the task if it runs longer than» 2 часа

В примере установка только на 23 машины бухгалтеров. Для развёртывания на все машины разом (без разделения на отделы) можно использовать разбивку на группы (по 20 единиц):

$groups = $computers | Select-Object -First 100 | Select-Object -Skip 0 -First 20

Использовать для развёртывания будем скрипт:

# Импорт из .csv + фильтр для бухов $computers = Import-Csv -Path "C:\IT\Deployment\computers.csv" |               Where-Object { $_.Department -eq "Бухгалтерия" } |               Select-Object -ExpandProperty ComputerName  # Проверяем компьютеры if (-not $computers) {     Write-Warning "Не найдено компьютеров отдела Бухгалтерия в CSV файле"     exit }  # Путь к ZIP-архиву с Chocolatey на сетевой шаре $chocoZipPath = "\\IT\Software\choco\chocolatey.zip" # Временный каталог для распаковки на машинах $tempChocoPath = "C:\Temp\ChocolateyInstall"  foreach ($computer in $computers) {     try {         # Проверяем доступность машины         if (-not (Test-Connection -ComputerName $computer -Count 1 -Quiet -ErrorAction SilentlyContinue)) {             Write-Warning "$computer недоступен"             Add-Content -Path "C:\IT\Deployment\failed.txt" -Value "$computer - недоступен по сети"             continue         }          # Устанавливаем Chocolatey из архива         $session = $null         try {             # Создаем сессию             $session = New-PSSession -ComputerName $computer -ErrorAction Stop                          Invoke-Command -Session $session -ScriptBlock {                 param($zipPath, $installPath)                                  # Создаем временный каталог                 if (-not (Test-Path $installPath)) {                     New-Item -ItemType Directory -Path $installPath -Force | Out-Null                 }                                  # Копируем архив на целевую машину                 $localZipPath = Join-Path $env:TEMP "chocolatey.zip"                 Copy-Item -Path $zipPath -Destination $localZipPath -Force                                  # Распаковываем архив                 try {                     Add-Type -AssemblyName System.IO.Compression.FileSystem                     [System.IO.Compression.ZipFile]::ExtractToDirectory($localZipPath, $installPath)                 } catch {                     Write-Warning "Ошибка распаковки Chocolatey: $_"                     throw                 }                                  # Добавляем путь к Chocolatey в переменную PATH                 $chocoBinPath = Join-Path $installPath "tools"                 $envPath = [Environment]::GetEnvironmentVariable("PATH", "Machine")                 if (-not $envPath.Contains($chocoBinPath)) {                     [Environment]::SetEnvironmentVariable(                         "PATH",                          "$envPath;$chocoBinPath",                          "Machine"                     )                     $env:PATH += ";$chocoBinPath"                 }                                  # Устанавливаем переменную окружения ChocolateyInstall                 [Environment]::SetEnvironmentVariable(                     "ChocolateyInstall",                      $installPath,                      "Machine"                 )                                  # Добавляем локальный репозиторий                 Start-Sleep -Seconds 5 # Даем время для инициализации                 &amp; choco source add -n="LocalRepo" -s="\\IT\Software\choco" --priority=1 -ErrorAction Stop                                  # Устанавливаем пакет                 &amp; choco install buh-software -y --source=LocalRepo --force -ErrorAction Stop                                  # Очищаем временные файлы                 Remove-Item $localZipPath -Force -ErrorAction SilentlyContinue                              } -ArgumentList $chocoZipPath, $tempChocoPath -ErrorAction Stop              Write-Host "$computer : установка завершена успешно" -ForegroundColor Green         } catch {             Write-Warning "Ошибка на $computer : $_"             Add-Content -Path "C:\IT\Deployment\failed.txt" -Value "$computer - ошибка установки: $_"         } finally {             if ($session) { Remove-PSSession -Session $session }         }     }     catch {         Write-Warning "Ошибка при обработке $computer : $_"         Add-Content -Path "C:\IT\Deployment\failed.txt" -Value "$computer - ошибка обработки: $_"     } }

После успешного развёртывания ПО на всех машинах удалось достичь следующего:

  1. Временные показатели:

    • Ручная установка занимает ~40 минут на машину × 100 = ~66 часов;

    • Установка с помощью Chocolatey: ~10 часов (с подготовкой и созданием 5 пакетов для разных отделов);

    • Экономия: 56 часов рабочего времени.

  2. Масштабируемость:

    • Данное решение готово к развёртыванию на новых машинах/обновлению ПО на старых;

    • Процесс установки новых версий ПО упрощён в разы.

Итог

  1. Решение, описанное в статье, позволяет развёртывать и создавать собственные пакеты ПО для разных нужд и отделов на множестве корпоративных компьютеров с минимальными затратами труда.

  2. Данный подход не является совершенным, что было описано в начале статьи. Опыт показал, что решение хоть и легко масштабируется, но является не самым быстрым. Для себя решил, что обязательно буду рассматривать внедрение Nexus Repository или его аналогов.


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

P.S. Я запустил свою группу в Телеграмм, буду рад видеть всех, кому интересен процесс написания скриптов и автоматизация в мире IT.


ссылка на оригинал статьи https://habr.com/ru/articles/922164/


Комментарии

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

Ваш адрес email не будет опубликован. Обязательные поля помечены *