Представьте ситуацию: на корпоративных компьютерах сломалось обновление, версия ПО устарела, или после миграции на новый сервер часть приложений просто перестала запускаться. Перестанавливать вручную десятки, а то и сотни машин — это потерянные часы. PowerShell позволяет автоматизировать этот процесс: написать один скрипт, запустить его на нужных компьютерах и получить чистую, актуальную версию со всеми настройками. Ниже — практическое руководство, как это сделать без лишней теории и с пониманием подводных камней.
- Когда массовая переустановка действительно нужна
- Что нужно перед запуском скрипта
- Как найти точное имя приложения в системе
- Базовый скрипт: удаление и установка
- Массовый запуск на нескольких компьютерах
- Работа с .exe-установщиками
- Обработка ошибок и логирование
- Частые ошибки и как их избежать
- Сценарии в зависимости от ситуации
- Как проверить результат
- Рекомендации по организации процесса
- Итог
Когда массовая переустановка действительно нужна
Не стоит хвататься за скрипт ради скрипта. Массовая переустановка приложений через PowerShell оправдана в нескольких случаях:
- Необходимо обновить версию ПО на большом парке машин до конкретной сборки.
- Приложение повреждено после обновления ОС или другого ПО, и обычный
repairне помогает. - Требуется сменить версию с изменением параметров установки (другой путь, новые компоненты).
- Происходит миграция с одного дистрибутива на другой, и старый нужно полностью удалить перед установкой нового.
- В домене нет SCCM / Intune, но есть централизованный доступ к компьютерам через WinRM.
Если у вас 2–3 компьютера, проще переустановить вручную. Если 10 и больше — автоматизация начинает экономить реальное время.
Что нужно перед запуском скрипта
Прежде чем писать скрипт, убедитесь, что выполнены подготовительные условия. Без этого скрипт либо не сработает, либо приведёт к неожиданным результатам.
- Права администратора. Для удаления и установки приложений скрипт должен запускаться с повышенными привилегиями. На удалённых машинах — через учётную запись с локальными правами admin или через систему управления доступом (LAPS, gMSA).
- Доступ к сетевой папке с дистрибутивами. Установочные файлы (.msi, .exe) должны быть доступны с каждого целевого компьютера. Лучше всего — общая SMB-шара с правами на чтение для учётной записи, под которой выполняется скрипт.
- WinRM включён и настроен. Если вы планируете запускать скрипт удалённо через
Invoke-Command, убедитесь, что WinRM запущен на целевых машинах и разрешён в брандмауэре. - Список целевых компьютеров. Соберите список машин — из Active Directory, из CSV-файла или из текстового файла. Проверьте, что все они в сети и доступны.
- Тестовый запуск на одной машине. Никогда не запускайте массовую переустановку сразу на всех. Сначала проверьте на тестовом компьютере.
Как найти точное имя приложения в системе
Это один из самых важных и самых недооценённых шагов. Если вы неправильно укажете имя приложения, скрипт либо не найдёт его, либо удалит не то, либо вообще не сработает.
Есть несколько способов получить точное имя:
- Реестр. Откройте
regeditи перейдите вHKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall. Просмотрите подразделы — в параметреDisplayNameбудет точное имя приложения. - Командная строка. Выполните
wmic product get name— получите список всех приложений, установленных через MSI. Минус: работает медленно и запускает проверку всех пакетов. - PowerShell. Команда
Get-ItemProperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\* | Select-Object DisplayNameдаст список установленных программ с отображением имён.
Для приложений, установленных через MSI, также важен ProductCode — GUID пакета. Его можно найти в том же разделе реестра, в параметре PSChildName или через Get-ItemProperty с фильтром по имени.
Базовый скрипт: удаление и установка
Вот минимальный, но рабочий пример скрипта, который удаляет приложение и устанавливает его заново:
# Параметры
$AppName = "Имя Приложения"
$InstallerPath = "\\server\share\application.msi"
$ComputerName = "COMPUTER01"
# Удаление
Invoke-Command -ComputerName $ComputerName -ScriptBlock {
param($AppName)
$app = Get-ItemProperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\* |
Where-Object { _.DisplayName -eqAppName }
if ($app) {
msiexec.exe /x $app.PSChildName /qn /norestart
Write-Host "Приложение удалено"
} else {
Write-Host "Приложение не найдено"
}
} -ArgumentList $AppName
# Установка
Invoke-Command -ComputerName $ComputerName -ScriptBlock {
param($InstallerPath)
msiexec.exe /i $InstallerPath /qn /norestart
Write-Host "Установка завершена"
} -ArgumentList $InstallerPath Разберём, что здесь происходит:
/qn— тихая установка без интерфейса./norestart— предотвращает автоматическую перезагрузку (иначе скрипт может прерваться).Invoke-Commandс параметром-ComputerNameвыполняет команды удалённо через WinRM./x— удаление по ProductCode (GUID), что надёжнее, чем по имени.
Массовый запуск на нескольких компьютерах
Чтобы не вызывать скрипт для каждой машины отдельно, используйте цикл по списку компьютеров:
$Computers = Get-Content "C:\temp\computers.txt"
$AppName = "Имя Приложения"
$InstallerPath = "\\server\share\application.msi"
foreach (Computer inComputers) {
Write-Host "Обработка $Computer..." -ForegroundColor Cyan
try {
result = Invoke-Command -ComputerNameComputer -ScriptBlock {
param(AppName,InstallerPath)
# Удаление
$app = Get-ItemProperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\* |
Where-Object { _.DisplayName -eqAppName } -ErrorAction SilentlyContinue
if ($app) {
process = Start-Process msiexec.exe -ArgumentList "/x",app.PSChildName, "/qn", "/norestart" -Wait -PassThru
if ($process.ExitCode -ne 0) {
Write-Warning "Ошибка удаления: код (process.ExitCode)"
}
}
# Установка
installProcess = Start-Process msiexec.exe -ArgumentList "/i",InstallerPath, "/qn", "/norestart" -Wait -PassThru
return $installProcess.ExitCode
} -ArgumentList AppName,InstallerPath -ErrorAction Stop
if ($result -eq 0) {
Write-Host "Успешно на $Computer" -ForegroundColor Green
} else {
Write-Warning "Проблема на Computer, код:result"
}
} catch {
Write-Error "Не удалось подключиться к $_"
}
} Обратите внимание на использование Start-Process с параметром -Wait вместо прямого вызова msiexec.exe. Это позволяет дождаться завершения установки перед переходом к следующему шагу и получить код возврата для диагностики.
Работа с .exe-установщиками
Не все приложения ставятся через MSI. Для .exe-установщиков нужно знать ключи тихой установки. Вот основные варианты:
| Тип установщика | Ключ тихой установки | Ключ удаления | Примечание |
|---|---|---|---|
| InstallShield | /s /v/qn | /s /x | Иногда требуется /sms для ожидания завершения |
| Inno Setup | /VERYSILENT /SUPPRESSMSGBOXES | /VERYSILENT /SUPPRESSMSGBOXES /uninstall | Можно добавNORESTART для подавления перезагрузки |
| NSIS | /S | /S _?="путь_к_папке_установки" | Удаление может не поддерживаться через ключ |
| WiX Burn | /q /norestart | /x /q /norestart | Аналогично MSI-пакетам |
Если вы не знаете ключи тихой установки для конкретного .exe, попробуйте запустить setup.exe /? — часто выводится справка по ключам. Также полезный ресурс — silentinstall.org и документация вендора.
Обработка ошибок и логирование
При массовой переустановке критически важно вести журнал событий. Что пошло не так на машине №14 из 50 — без логов вы не узнаете.
LogFile = "C:tempapp_reinstall_log_(Get-Date -Format 'yyyyMMdd_HHmmss').log"
function Write-Log {
param(Message,Level = "INFO")
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
entry = "[timestamp] [Level]Message"
Add-Content -Path LogFile -Valueentry
switch ($Level) {
"ERROR" { Write-Host $entry -ForegroundColor Red }
"WARNING" { Write-Host $entry -ForegroundColor Yellow }
default { Write-Host $entry }
}
}
# Использование в основном скрипте
foreach (Computer inComputers) {
Write-Log "Начинаем обработку $Computer"
try {
# ... основной код ...
Write-Log "Успешно на $Computer"
} catch {
Write-Log "Ошибка на Computer :_" -Level "ERROR"
}
} Также полезно проверять коды возврата msiexec. Основные варианты:
0— успешно.3010— успешно, но требуется перезагрузка.1602— пользователь отменил установку (может означать проблему с правами).1603— фатальная ошибка при установке (повреждённый пакет, конфликт, нет места на диске).1618— другая установка уже выполняется (конфликт с другим процессом).
Частые ошибки и как их избежать
Вот реальные проблемы, с которыми сталкиваются при массовой переустановке через PowerShell:
- Приложение не находится по имени. Имя в реестре может отличаться от того, что вы видите в «Программы и компонентах». Используйте фильтр по реестру и проверяйте точное написание, включая пробелы и знаки препинания.
- WinRM не работает на целевых машинах. Проверьте: служба WinRM запущена (
Get-Service WinRM), в брандмауэре разрешён порт 5985 (HTTP) или 5986 (HTTPS), и выполненEnable-PSRemoting -Force. - Установка запускается, но не дожидается завершения. Без параметра
-WaitвStart-Processскрипт переходит к следующему шагу мгновенно. Всегда используйте-Waitдля установщиков. - Двойная аутентификация (double-hop). Когда скрипт подключается к удалённому компьютеру, а оттуда обращается к сетевой папке — возникает ошибка доступа. Решение: используйте CredSSP, либо копируйте дистрибутив локально на целевую машину перед запуском установки.
- Скрипт удаляет приложение, но не может установить заново. Проверьте, не блокирует ли антивирус запуск установщика. Также убедитесь, что предыдущая версия полностью удалена — иногда требуется перезагрузка между удалением и установкой.
- Нет места на диске. Перед установкой имеет смысл проверить свободное место на системном диске:
Get-PSDrive C | Select-Object Free.
Сценарии в зависимости от ситуации
Ситуация 1: У вас есть SCCM или Intune. В этом случае PowerShell — не лучший выбор для массовой переустановки. Используйте встроенные инструменты развёртывания: в SCCM — задачу переустановки приложения, в Intune — назначение приложения с обязательной переустановкой. PowerShell здесь полезен только как вспомогательное средство для проверки состояния.
Ситуация 2: Домен без централизованного управления, есть доступ к сетевой папке. Используйте PowerShell с Invoke-Command и списком компьютеров из текстового файла. Это самый распространённый сценарий для небольших и средних организаций.
Ситуация 3: Приложение установлено не на всех компьютерах. Добавьте проверку: если приложение не найдено — пропускаем удаление и сразу ставим. Если найдено — удаляем и ставим. Это универсальный подход, который работает и для «чистой» установки, и для переустановки.
Ситуация 4: Нужна переустановка с сохранением пользовательских настроек. Здесь всё зависит от конкретного приложения. Некоторые поддерживают ключ /qn REBOOT=ReallySuppress PRESERVECONFIG=1 или аналогичные. Другие требуют экспорта настроек перед удалением и импорта после. Изучите документацию приложения — универсального решения нет.
Как проверить результат
После выполнения скрипта не полагайтесь на то, что «ошибок не было — значит, всё прошло». Проверьте результат:
# Проверка на списке компьютеров
$Computers = Get-Content "C:\temp\computers.txt"
$AppName = "Имя Приложения"
results = Invoke-Command -ComputerNameComputers -ScriptBlock {
param($AppName)
$app = Get-ItemProperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\* |
Where-Object { _.DisplayName -eqAppName } -ErrorAction SilentlyContinue
if ($app) {
[PSCustomObject]@{
Computer = $env:COMPUTERNAME
Installed = $true
Version = $app.DisplayVersion
Status = "OK"
}
} else {
[PSCustomObject]@{
Computer = $env:COMPUTERNAME
Installed = $false
Version = $null
Status = "NOT FOUND"
}
}
} -ArgumentList $AppName
$results | Format-Table -AutoSize
results | Where-Object_.Status -eq "NOT FOUND" } | Format-Table -AutoSize Этот скрипт покажет, на каких компьютерах приложение установлено и с какой версией. Отфильтруйте те, где статус «NOT FOUND» — это машины, на которых что-то пошло не так.
Рекомендации по организации процесса
- Ведите версионность скриптов. Храните скрипты в Git или хотя бы с датами в именах файлов. Когда через месяц понадобится повторить процедуру, вы скажете себе спасибо.
- Используйте параметризованные скрипты. Выносите имя приложения, путь к установщику и список компьютеров в переменные или параметры скрипта. Не хардкодьте значения внутри кода.
- Делайте бэкап перед массовым удалением. Если переустановка идёт на продакшен-серверах, убедитесь, что у вас есть снимок системы или резервная копия. Откат должен быть возможен.
- Уведомляйте пользователей. Если приложение переустанавливается на рабочих станциях людей, предупредите их заранее. Тихая переустановка может прервать работу, если приложение было запущено.
- Тестируйте на группе из 3–5 машин. Запустите скрипт сначала на тестовой группе, проверьте результат, и только потом масштабируйте на весь парк.
Итог
PowerShell — удобный и доступный инструмент для массовой переустановки приложений, особенно когда у вас нет корпоративных систем управления вроде SCCM или Intune. Ключевые шаги: подготовить список компьютеров, убедиться в доступности дистрибутивов и WinRM, написать скрипт с обработкой ошибок и логированием, протестировать на нескольких машинах и только потом запускать массово.
Главное правило — не торопиться. Лучше потратить лишние 30 минут на проверку и тестирование, чем потом разбираться, почему на 20 компьютерах из 100 приложение не запускается. Начните с простого скрипта на одной машине, убедитесь, что он работает корректно, и только потом масштабируйте.
