Загрузка данных
1) Создать папку в которой будут хранится watcher.ps1, установщик. Также в этой папке создать папку EKP
2) В сетевой папке создать D:\win10\Share\App создать папки KOE, KOEIZ, KPE, PPK
3) Запустить watcher и далее запустить скрипт на vdi
-- Поправить пути к файлам под себя
Если все нормально можно сделать автозапуск через шедулер
schtasks /Create /TN "MyPowerShellScript" /TR "powershell.exe -NoProfile -ExecutionPolicy Bypass -File \"C:\Users\vboxuser\Desktop\123.ps1"" /SC DAILY /ST 00:22 /RU "vboxuser" /RP "1234" /RL HIGHEST
Включить в настройках в Параметрах - > Немедленно запускать задачу, если пропущен плановый запуск
# ============================================================
# Скрипт забора архивов с FTP
# Скачивает RAR-архивы в локальные папки, НЕ распаковывает.
# Ведёт файл-маркер версии, чтобы не качать повторно.
# ============================================================
# --- Настройки FTP ---
$ftpHost = "10.0.2.15"
$ftpPath = "/AisNalog3"
$ftpUser = "anonymous"
$ftpPassword = ""
# --- Локальные пути ---
$localBasePath = "Z:/App"
$flagFile = "$localBasePath/success.flag"
# --- Соответствие удалённых папок локальным ---
$folderMapping = @{
"Prom" = "KPE"
"PredProm" = "PPK"
"OE" = "KOE"
"OEIZ" = "KOEIZ"
}
# --- Шаблон имени файла-маркера версии: например 26_8_18_1 ---
$versionPattern = '^\d+_\d+_\d+_\d+$'
# ============================================================
# ФУНКЦИИ
# ============================================================
# Получить список папок с датами через FTP (LIST -la)
function Get-FtpFoldersWithDates {
param([string]$ftpPath)
$folders = @{}
try {
$uri = "ftp://$ftpHost$ftpPath/"
$request = [System.Net.FtpWebRequest]::Create($uri)
$request.Method = [System.Net.WebRequestMethods+Ftp]::ListDirectoryDetails
$request.Credentials = New-Object System.Net.NetworkCredential($ftpUser, $ftpPassword)
$request.UseBinary = $true
$request.UsePassive = $true
$request.EnableSsl = $false
$request.KeepAlive = $false
$request.Timeout = 30000
$response = $request.GetResponse()
$stream = $response.GetResponseStream()
$reader = New-Object System.IO.StreamReader($stream)
$listing = $reader.ReadToEnd()
$reader.Close()
$response.Close()
$lines = $listing -split "`r?`n" | Where-Object { $_ -ne "" }
foreach ($line in $lines) {
$isDirectory = $false
$folderName = $null
$dateTime = $null
# Unix-style: drwxr-xr-x ... name
if ($line -match "^d.*\s+(\S+)$") {
$folderName = $matches[1]
$isDirectory = $true
if ($line -match "(\w{3})\s+(\d{1,2})\s+(\d{2}:\d{2})") {
$month = $matches[1]; $day = $matches[2]; $time = $matches[3]
$currentYear = (Get-Date).Year
try {
$dateTime = [DateTime]::ParseExact("$month $day $currentYear $time", "MMM d yyyy HH:mm", [System.Globalization.CultureInfo]::InvariantCulture)
} catch {
try {
$dateTime = [DateTime]::ParseExact("$month $day $currentYear $time", "MMM dd yyyy HH:mm", [System.Globalization.CultureInfo]::InvariantCulture)
} catch { $dateTime = $null }
}
}
}
# Windows IIS-style: <DIR> name
elseif ($line -match "<DIR>\s+(\S+)$") {
$folderName = $matches[1]
$isDirectory = $true
if ($line -match "(\d{2}-\d{2}-\d{2})\s+(\d{2}:\d{2}[AP]M)") {
try {
$dateTime = [DateTime]::ParseExact("$($matches[1]) $($matches[2])", "MM-dd-yy hh:mmtt", [System.Globalization.CultureInfo]::InvariantCulture)
} catch { $dateTime = $null }
}
}
if ($isDirectory -and $folderName -and $folderName -ne "." -and $folderName -ne "..") {
if ($dateTime) { $folders[$folderName] = $dateTime }
else { $folders[$folderName] = [DateTime]::MinValue }
}
}
return $folders
}
catch {
Write-Host " Ошибка при получении списка папок: $_" -ForegroundColor Red
return @{}
}
}
# Получить простой список файлов в папке FTP
function Get-FtpFileList {
param([string]$ftpPath)
$items = @()
try {
$uri = "ftp://$ftpHost$ftpPath/"
$request = [System.Net.FtpWebRequest]::Create($uri)
$request.Method = [System.Net.WebRequestMethods+Ftp]::ListDirectory
$request.Credentials = New-Object System.Net.NetworkCredential($ftpUser, $ftpPassword)
$request.UseBinary = $true
$request.UsePassive = $true
$request.EnableSsl = $false
$request.KeepAlive = $false
$request.Timeout = 30000
$response = $request.GetResponse()
$stream = $response.GetResponseStream()
$reader = New-Object System.IO.StreamReader($stream)
$listing = $reader.ReadToEnd()
$reader.Close()
$response.Close()
$lines = $listing -split "`r?`n" | Where-Object { $_ -ne "" }
foreach ($line in $lines) { $items += $line.Trim() }
return $items
}
catch {
Write-Host " Ошибка при получении списка файлов: $_" -ForegroundColor Red
return @()
}
}
# Найти локальный файл-маркер версии в папке
function Get-LocalVersionFile {
param([string]$localFolderPath)
if (!(Test-Path $localFolderPath)) { return $null }
$files = Get-ChildItem -Path $localFolderPath -File -Force -ErrorAction SilentlyContinue
foreach ($f in $files) {
if ($f.BaseName -match $versionPattern) {
return $f
}
}
return $null
}
# Обновить (переименовать/создать) локальный файл-маркер версии
function Update-VersionFile {
param(
[string]$localFolderPath,
[string]$latestFolder,
[System.IO.FileInfo]$localVersionFile
)
try {
if ($localVersionFile) {
if ($localVersionFile.BaseName -eq $latestFolder) {
return
}
$extension = $localVersionFile.Extension
if ([string]::IsNullOrEmpty($extension)) { $extension = ".txt" }
$newName = "$latestFolder$extension"
Rename-Item -Path $localVersionFile.FullName -NewName $newName -Force
Write-Host " Файл версии переименован: $($localVersionFile.Name) -> $newName" -ForegroundColor Green
}
else {
$newName = "$latestFolder.txt"
$newPath = Join-Path $localFolderPath $newName
New-Item -ItemType File -Path $newPath -Force | Out-Null
Write-Host " Создан файл версии: $newName" -ForegroundColor Green
}
}
catch {
Write-Host " Ошибка при обновлении файла версии: $_" -ForegroundColor Red
}
}
# Скачать один файл с FTP в локальный путь
function Download-FtpFile {
param(
[string]$remoteUri,
[string]$localPath
)
try {
$request = [System.Net.FtpWebRequest]::Create($remoteUri)
$request.Method = [System.Net.WebRequestMethods+Ftp]::DownloadFile
$request.Credentials = New-Object System.Net.NetworkCredential($ftpUser, $ftpPassword)
$request.UseBinary = $true
$request.UsePassive = $true
$request.EnableSsl = $false
$request.Timeout = 60000
$response = $request.GetResponse()
$ftpStream = $response.GetResponseStream()
$localStream = [System.IO.File]::Create($localPath)
$bufferSize = 8192
$buffer = New-Object Byte[] $bufferSize
$bytesRead = $ftpStream.Read($buffer, 0, $bufferSize)
$totalBytes = 0
$nextProgress = 1
while ($bytesRead -gt 0) {
$localStream.Write($buffer, 0, $bytesRead)
$totalBytes += $bytesRead
$bytesRead = $ftpStream.Read($buffer, 0, $bufferSize)
$currentMB = [math]::Floor($totalBytes / 1MB)
if ($currentMB -ge $nextProgress) {
$nextProgress = $currentMB + 1
Write-Host " Прогресс скачивания: $currentMB MB" -ForegroundColor Gray
}
}
$localStream.Close()
$ftpStream.Close()
$response.Close()
$fileSize = [math]::Round($totalBytes / 1MB, 2)
Write-Host " Файл скачан: $localPath (Размер: $fileSize MB)" -ForegroundColor Green
return $true
}
catch {
Write-Host " Ошибка при скачивании: $_" -ForegroundColor Red
if (Test-Path $localPath) { Remove-Item $localPath -Force -ErrorAction SilentlyContinue }
return $false
}
}
# Обработка одной удалённой папки:
# 1) найти самую новую подпапку на FTP
# 2) сравнить с локальным файлом-маркером версии
# 3) если версия неактуальна — скачать RAR (без распаковки) и обновить маркер
function Download-ArchivesFromFTP {
param(
[string]$remoteFolder,
[string]$localFolder
)
Write-Host "Обработка папки: $remoteFolder" -ForegroundColor Yellow
$remoteBasePath = "$ftpPath/$remoteFolder"
$localFolderPath = Join-Path $localBasePath $localFolder
if (!(Test-Path $localFolderPath)) {
New-Item -ItemType Directory -Path $localFolderPath -Force | Out-Null
Write-Host " Создана локальная папка: $localFolderPath" -ForegroundColor Gray
}
# --- Список подпапок с датами ---
Write-Host " Получение списка папок из: ftp://$ftpHost$remoteBasePath/" -ForegroundColor Gray
$foldersWithDates = Get-FtpFoldersWithDates -ftpPath $remoteBasePath
if ($foldersWithDates.Count -eq 0) {
Write-Host " В папке $remoteFolder нет подпапок" -ForegroundColor Red
return $false
}
Write-Host " Найдено папок: $($foldersWithDates.Count)" -ForegroundColor Gray
foreach ($folder in $foldersWithDates.Keys) {
$date = $foldersWithDates[$folder]
if ($date -ne [DateTime]::MinValue) {
Write-Host " $folder — $($date.ToString('dd.MM.yyyy HH:mm'))" -ForegroundColor Gray
} else {
Write-Host " $folder — дата не определена" -ForegroundColor Gray
}
}
# --- Самая новая подпапка ---
$latestFolder = $null
$latestDate = [DateTime]::MinValue
foreach ($folder in $foldersWithDates.Keys) {
$date = $foldersWithDates[$folder]
if ($date -gt $latestDate) {
$latestDate = $date
$latestFolder = $folder
}
}
if (-not $latestFolder) {
Write-Host " Не удалось определить самую новую папку" -ForegroundColor Red
return $false
}
Write-Host " Самая новая папка: $latestFolder ($($latestDate.ToString('dd.MM.yyyy HH:mm')))" -ForegroundColor Green
# === Проверка актуальности локальной версии ===
$localVersionFile = Get-LocalVersionFile -localFolderPath $localFolderPath
if ($localVersionFile) {
Write-Host " Локальный файл версии: $($localVersionFile.Name)" -ForegroundColor Gray
if ($localVersionFile.BaseName -eq $latestFolder) {
Write-Host " Версия актуальна ($($localVersionFile.BaseName) = $latestFolder). Пропускаем." -ForegroundColor Green
return $true
} else {
Write-Host " Версия неактуальна ($($localVersionFile.BaseName) <> $latestFolder). Забираем архив." -ForegroundColor Yellow
}
} else {
Write-Host " Локальный файл версии не найден. Забираем архив." -ForegroundColor Yellow
}
# ============================================
# --- Проверяем EKP ---
$ekpPath = "$remoteBasePath/$latestFolder/EKP"
Write-Host " Проверка EKP: ftp://$ftpHost$ekpPath/" -ForegroundColor Gray
$ekpFiles = Get-FtpFileList -ftpPath $ekpPath
if ($ekpFiles.Count -eq 0) {
Write-Host " Папка EKP пуста или не существует" -ForegroundColor Red
return $false
}
Write-Host " Найдено файлов в EKP: $($ekpFiles.Count)" -ForegroundColor Gray
Write-Host " Файлы: $($ekpFiles -join ', ')" -ForegroundColor Gray
# --- Ищем RAR ---
$archives = @()
foreach ($file in $ekpFiles) {
if ($file -match "\.rar$") { $archives += $file }
}
if ($archives.Count -eq 0) {
Write-Host " В EKP не найдено RAR архивов" -ForegroundColor Red
Write-Host " Доступные файлы: $($ekpFiles -join ', ')" -ForegroundColor Yellow
return $false
}
Write-Host " Найдены RAR архивы: $($archives -join ', ')" -ForegroundColor Gray
$archiveToDownload = $archives[0]
if ($archives.Count -gt 1) {
Write-Host " Найдено несколько архивов, выбран: $archiveToDownload" -ForegroundColor Yellow
}
$localFilePath = Join-Path $localFolderPath $archiveToDownload
# --- Файл уже есть локально ---
if (Test-Path $localFilePath) {
$fileSize = [math]::Round((Get-Item $localFilePath).Length / 1MB, 2)
Write-Host " Файл уже существует: $localFilePath ($fileSize MB)" -ForegroundColor Yellow
# Обновляем маркер версии, раз архив уже на месте
Update-VersionFile -localFolderPath $localFolderPath -latestFolder $latestFolder -localVersionFile $localVersionFile
return $true
}
# --- Скачиваем ---
Write-Host " Скачивание: $archiveToDownload" -ForegroundColor Cyan
Write-Host " В локальную папку: $localFolderPath" -ForegroundColor Cyan
$downloadUri = "ftp://$ftpHost$ekpPath/$archiveToDownload"
if (Download-FtpFile -remoteUri $downloadUri -localPath $localFilePath) {
Update-VersionFile -localFolderPath $localFolderPath -latestFolder $latestFolder -localVersionFile $localVersionFile
return $true
}
return $false
}
# ============================================================
# ОСНОВНАЯ ЛОГИКА
# ============================================================
Write-Host "========================================" -ForegroundColor Cyan
Write-Host "ЗАБОР АРХИВОВ С FTP (БЕЗ РАСПАКОВКИ)" -ForegroundColor Cyan
Write-Host "========================================" -ForegroundColor Cyan
Write-Host "FTP-хост: $ftpHost" -ForegroundColor Yellow
Write-Host "FTP-путь: $ftpPath" -ForegroundColor Yellow
Write-Host "Локальная: $localBasePath" -ForegroundColor Yellow
Write-Host "========================================" -ForegroundColor Cyan
Write-Host ""
$successCount = 0
$totalCount = $folderMapping.Count
$downloadResults = @{}
foreach ($remoteFolder in $folderMapping.Keys) {
$localFolder = $folderMapping[$remoteFolder]
Write-Host "`n>> Обработка: $remoteFolder -> $localFolder" -ForegroundColor Magenta
if (Download-ArchivesFromFTP -remoteFolder $remoteFolder -localFolder $localFolder) {
$successCount++
$downloadResults[$remoteFolder] = $true
} else {
$downloadResults[$remoteFolder] = $false
}
Write-Host "----------------------------------------" -ForegroundColor Gray
}
Write-Host "`n========================================" -ForegroundColor Cyan
Write-Host "РЕЗУЛЬТАТЫ:" -ForegroundColor Cyan
foreach ($remoteFolder in $folderMapping.Keys) {
$localFolder = $folderMapping[$remoteFolder]
$status = if ($downloadResults[$remoteFolder]) { "УСПЕШНО" } else { "ОШИБКА" }
$color = if ($downloadResults[$remoteFolder]) { "Green" } else { "Red" }
Write-Host " $remoteFolder -> $localFolder : $status" -ForegroundColor $color
}
Write-Host "========================================" -ForegroundColor Cyan
Write-Host "Успешно: $successCount из $totalCount" -ForegroundColor Yellow
# --- success.flag создаём только если все папки успешны ---
if ($successCount -eq $totalCount) {
try {
if (!(Test-Path $localBasePath)) {
New-Item -ItemType Directory -Path $localBasePath -Force | Out-Null
}
$flagContent = "Скачивание архивов завершено: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')`r`n"
$flagContent += "Обработано папок: $successCount из $totalCount`r`n`r`n"
$flagContent += "Скачанные архивы:`r`n"
foreach ($remoteFolder in $folderMapping.Keys) {
$localFolder = $folderMapping[$remoteFolder]
$localFolderPath = Join-Path $localBasePath $localFolder
if (Test-Path $localFolderPath) {
$files = Get-ChildItem -Path $localFolderPath -File -Filter "*.rar"
if ($files.Count -gt 0) {
foreach ($file in $files) {
$size = [math]::Round($file.Length / 1MB, 2)
$flagContent += " $localFolder : $($file.Name) ($size MB)`r`n"
}
} else {
$flagContent += " $localFolder : (нет .rar)`r`n"
}
} else {
$flagContent += " $localFolder : (папка не создана)`r`n"
}
}
$flagContent | Out-File -FilePath $flagFile -Encoding UTF8
Write-Host "`nФайл success.flag создан: $flagFile" -ForegroundColor Green
Write-Host "Содержимое success.flag:" -ForegroundColor Gray
Write-Host $flagContent -ForegroundColor Gray
}
catch {
Write-Host "Ошибка при создании success.flag: $_" -ForegroundColor Red
}
} else {
Write-Host "`nНе все папки обработаны успешно. success.flag не создан." -ForegroundColor Red
}
Write-Host "`nСкрипт завершён." -ForegroundColor Cyan
Read-Host "123"
#Start-Sleep -Seconds 10
#exit
Сетевая папка -> KOE, KOEIZ, KPE, PPK
Папка App2 - > папка KPE
# =====================================================
# Скрипт автоматической установки/переустановки MSI
# Логика:
# 1. Из папки-источника (D:\win10\Share\App\KPE и т.д.) берём .rar
# 2. Копируем в D:\services\Рабочий стол\App2\EKP
# 3. Распаковываем WinRAR'ом
# 4. Ищем .msi в распакованном, ставим
# 5. Чистим EKP и папку-источник (кроме .txt)
# 6. Переходим к следующей папке
# =====================================================
# --- 1. Проверка прав администратора ---
$currentPrincipal = New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent())
$isAdmin = $currentPrincipal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
if (-not $isAdmin) {
Write-Host "ОШИБКА: скрипт запущен без прав администратора!" -ForegroundColor Red
Write-Host "Проверьте, что watcher запущен от имени администратора." -ForegroundColor Red
Start-Sleep -Seconds 5
exit 1
}
Write-Host "=== АВТОМАТИЧЕСКАЯ УСТАНОВКА/ПЕРЕУСТАНОВКА ПРОГРАММ ===" -ForegroundColor Cyan
Write-Host "Запущено от имени администратора" -ForegroundColor Green
# --- 2. Пути ---
# Папка-источник, где лежат KPE, PPK, KOE, KOE IZ
$rootFolder = "D:\win10\Share\App"
# Рабочая папка для распаковки
$workBase = "D:\services\Рабочий стол\App2"
$ekpFolder = Join-Path $workBase "EKP"
# Путь к WinRAR
$winRarPath = "C:\Program Files\WinRAR\WinRAR.exe"
if (!(Test-Path $winRarPath)) {
$winRarPath = "C:\Program Files (x86)\WinRAR\WinRAR.exe"
}
if (!(Test-Path $winRarPath)) {
Write-Host "ОШИБКА: WinRAR не найден по стандартным путям!" -ForegroundColor Red
Write-Host "Укажите правильный путь в переменной `$winRarPath" -ForegroundColor Red
Start-Sleep -Seconds 10
exit 1
}
Write-Host "Папка-источник: $rootFolder" -ForegroundColor Cyan
Write-Host "Рабочая папка: $workBase" -ForegroundColor Cyan
Write-Host "EKP: $ekpFolder" -ForegroundColor Cyan
Write-Host "WinRAR: $winRarPath" -ForegroundColor Cyan
Write-Host ""
# --- 3. Список программ ---
$programs = @(
@{ Folder = "KPE"; Name = "АИС Пром КПЕ" }
@{ Folder = "PPK"; Name = "АИС Пром ППК" }
@{ Folder = "KOE"; Name = "АИС Пром КОЕ" }
@{ Folder = "KOEIZ"; Name = "АИС Пром КОЕ ИЗ" }
)
# =====================================================
# ФУНКЦИИ
# =====================================================
# Поиск установленной программы
function Find-InstalledProgram {
param([string]$exactName)
Write-Host "Поиск программы: $exactName" -ForegroundColor Cyan
$foundPackage = Get-Package -Name $exactName -ErrorAction SilentlyContinue |
Select-Object -First 1
if (-not $foundPackage) {
$foundPackage = Get-Package -Name "*$exactName*" -ErrorAction SilentlyContinue |
Select-Object -First 1
}
if ($foundPackage) {
Write-Host "Программа найдена: $($foundPackage.Name) (v$($foundPackage.Version))" -ForegroundColor Green
} else {
Write-Host "Программа не найдена" -ForegroundColor Gray
}
return $foundPackage
}
# Удаление программы
function Uninstall-Program {
param(
[string]$displayName,
$package
)
Write-Host "Удаление программы: $displayName" -ForegroundColor Yellow
try {
Uninstall-Package -InputObject $package -Force -ErrorAction Stop
Write-Host "Удаление успешно завершено!" -ForegroundColor Green
Start-Sleep -Seconds 3
}
catch {
Write-Host "Ошибка при удалении: $($_.Exception.Message)" -ForegroundColor Red
}
}
# Полная очистка папки
function Clear-FolderFull {
param([string]$FolderPath)
if (-not (Test-Path $FolderPath)) {
Write-Host "Папка для очистки не найдена: $FolderPath" -ForegroundColor Yellow
return
}
Write-Host "Полная очистка папки: $FolderPath" -ForegroundColor Cyan
try {
Get-ChildItem -Path $FolderPath -Force -ErrorAction SilentlyContinue |
ForEach-Object {
Write-Host " Удаление: $($_.FullName)" -ForegroundColor Gray
Remove-Item -Path $_.FullName -Recurse -Force -ErrorAction SilentlyContinue
}
Write-Host "Очистка завершена" -ForegroundColor Green
}
catch {
Write-Host "Ошибка при очистке: $($_.Exception.Message)" -ForegroundColor Red
}
}
# Очистка папки, кроме .txt
function Clear-FolderExceptTxt {
param([string]$FolderPath)
if (-not (Test-Path $FolderPath)) {
Write-Host "Папка для очистки не найдена: $FolderPath" -ForegroundColor Yellow
return
}
Write-Host "Очистка папки (кроме .txt): $FolderPath" -ForegroundColor Cyan
try {
Get-ChildItem -Path $FolderPath -Directory -Recurse -ErrorAction SilentlyContinue |
ForEach-Object {
Write-Host " Удаление папки: $($_.FullName)" -ForegroundColor Gray
Remove-Item -Path $_.FullName -Recurse -Force -ErrorAction SilentlyContinue
}
Get-ChildItem -Path $FolderPath -File -Recurse -ErrorAction SilentlyContinue |
Where-Object { $_.Extension -ne ".txt" } |
ForEach-Object {
Write-Host " Удаление файла: $($_.Name)" -ForegroundColor Gray
Remove-Item -Path $_.FullName -Force -ErrorAction SilentlyContinue
}
Write-Host "Очистка завершена (оставлены только .txt)" -ForegroundColor Green
}
catch {
Write-Host "Ошибка при очистке: $($_.Exception.Message)" -ForegroundColor Red
}
}
# Распаковка RAR через WinRAR
function Extract-RarArchive {
param(
[string]$archivePath,
[string]$destinationPath
)
Write-Host "Распаковка: $archivePath" -ForegroundColor Cyan
Write-Host " в: $destinationPath" -ForegroundColor Gray
try {
$arguments = "x -o+ -y `"$archivePath`" `"$destinationPath\`""
$process = Start-Process -FilePath $winRarPath -ArgumentList $arguments -Wait -PassThru -NoNewWindow
if ($process.ExitCode -eq 0) {
Write-Host "Распаковка успешно завершена!" -ForegroundColor Green
return $true
} else {
Write-Host "Ошибка распаковки! Код: $($process.ExitCode)" -ForegroundColor Red
return $false
}
}
catch {
Write-Host "Ошибка при распаковке: $($_.Exception.Message)" -ForegroundColor Red
return $false
}
}
# Установка MSI
function Install-Msi {
param([string]$msiPath)
Write-Host "Установка MSI: $msiPath" -ForegroundColor Cyan
$installProcess = Start-Process -FilePath "msiexec.exe" `
-ArgumentList "/i `"$msiPath`" /quiet" `
-PassThru `
-WindowStyle Hidden
Write-Host "Установка запущена (PID: $($installProcess.Id))" -ForegroundColor Green
Write-Host "Ожидание завершения установки..." -ForegroundColor Cyan
Wait-Process -Id $installProcess.Id -ErrorAction SilentlyContinue
Write-Host "Установка MSI завершена" -ForegroundColor Green
}
# Поиск и запуск утилиты индексации
function Invoke-IndexationUtility {
param([string]$msiPath)
$exeToRun = "CommonComponents.Catalog.IndexationUtility.exe"
Write-Host "Поиск папки с установленной программой..." -ForegroundColor Cyan
$msiBaseName = [System.IO.Path]::GetFileNameWithoutExtension($msiPath)
Write-Host "Имя установщика: $msiBaseName" -ForegroundColor Gray
$programFolder = Get-ChildItem "C:\Program Files", "C:\Program Files (x86)" -Directory -ErrorAction SilentlyContinue |
Where-Object { $_.Name -eq $msiBaseName } |
Select-Object -First 1
if (-not $programFolder) {
Write-Host "Точное совпадение не найдено, ищем по частичному..." -ForegroundColor Yellow
$programFolder = Get-ChildItem "C:\Program Files", "C:\Program Files (x86)" -Directory -ErrorAction SilentlyContinue |
Where-Object { $_.Name -like "*$msiBaseName*" } |
Select-Object -First 1
}
if (-not $programFolder) {
Write-Host "Внимание: Папка с программой '$msiBaseName' не найдена" -ForegroundColor Yellow
return
}
Write-Host "Папка программы найдена: $($programFolder.FullName)" -ForegroundColor Green
$exePath = Join-Path $programFolder.FullName "Client" | Join-Path -ChildPath $exeToRun
$exePathRoot = Join-Path $programFolder.FullName $exeToRun
$finalExe = $null
if (Test-Path $exePath) {
$finalExe = $exePath
} elseif (Test-Path $exePathRoot) {
$finalExe = $exePathRoot
}
if (-not $finalExe) {
Write-Host "Внимание: Утилита $exeToRun не найдена" -ForegroundColor Red
return
}
Write-Host "Запуск утилиты: $finalExe" -ForegroundColor Cyan
try {
$utilityProcess = Start-Process -FilePath $finalExe -Wait -PassThru -WindowStyle Hidden -ErrorAction Stop
Write-Host "Утилита завершила работу (ExitCode: $($utilityProcess.ExitCode))" -ForegroundColor Green
}
catch {
Write-Host "ОШИБКА запуска утилиты: $($_.Exception.Message)" -ForegroundColor Red
}
}
# =====================================================
# ОБРАБОТКА ОДНОЙ ПРОГРАММЫ
# =====================================================
function Process-Program {
param(
[string]$folderName,
[string]$programName,
[string]$sourceFolder
)
Write-Host ""
Write-Host "=====================================================" -ForegroundColor Magenta
Write-Host ">>> Программа: $programName (папка $folderName)" -ForegroundColor Magenta
Write-Host "=====================================================" -ForegroundColor Magenta
# --- 1. Проверяем папку-источник ---
if (-not (Test-Path $sourceFolder)) {
Write-Host "Папка-источник не найдена: $sourceFolder" -ForegroundColor Red
return $false
}
# --- 2. Ищем .rar в папке-источнике ---
$rarFiles = Get-ChildItem -Path $sourceFolder -Filter "*.rar" -File -Recurse -ErrorAction SilentlyContinue
if ($rarFiles.Count -eq 0) {
Write-Host "В папке $folderName не найдено .rar архивов" -ForegroundColor Red
return $false
}
$rarToUse = $rarFiles | Select-Object -First 1
Write-Host "Найден архив: $($rarToUse.Name)" -ForegroundColor Green
# --- 3. Готовим EKP ---
if (Test-Path $ekpFolder) {
Clear-FolderFull -FolderPath $ekpFolder
} else {
New-Item -ItemType Directory -Path $ekpFolder -Force | Out-Null
Write-Host "Создана папка EKP: $ekpFolder" -ForegroundColor Gray
}
# --- 4. Копируем .rar в EKP ---
$localRarPath = Join-Path $ekpFolder $rarToUse.Name
Write-Host "Копирование архива: $($rarToUse.FullName) -> $localRarPath" -ForegroundColor Cyan
try {
Copy-Item -Path $rarToUse.FullName -Destination $localRarPath -Force -ErrorAction Stop
Write-Host "Архив скопирован" -ForegroundColor Green
}
catch {
Write-Host "ОШИБКА копирования архива: $($_.Exception.Message)" -ForegroundColor Red
return $false
}
# --- 5. Распаковываем ---
if (-not (Extract-RarArchive -archivePath $localRarPath -destinationPath $ekpFolder)) {
Write-Host "Распаковка не удалась, пропускаем $programName" -ForegroundColor Red
Clear-FolderFull -FolderPath $ekpFolder
return $false
}
# --- 6. Ищем .msi в распакованном ---
$msiFile = Get-ChildItem -Path $ekpFolder -Filter "*.msi" -File -Recurse -ErrorAction SilentlyContinue |
Select-Object -First 1
if (-not $msiFile) {
Write-Host "В распакованном архиве не найден .msi" -ForegroundColor Red
Clear-FolderFull -FolderPath $ekpFolder
return $false
}
$msiPath = $msiFile.FullName
Write-Host "Найден установщик: $($msiFile.Name)" -ForegroundColor Green
Write-Host "Путь: $msiPath" -ForegroundColor Gray
# --- 7. Удаляем старую версию ---
$existingPackage = Find-InstalledProgram -exactName $programName
if ($existingPackage) {
Write-Host "Программа найдена. Удаляем..." -ForegroundColor Yellow
Uninstall-Program -displayName $existingPackage.Name -package $existingPackage
} else {
Write-Host "Программа не найдена. Выполняется установка..." -ForegroundColor Green
}
# --- 8. Установка MSI ---
Install-Msi -msiPath $msiPath
Start-Sleep -Seconds 3
# --- 9. Запуск утилиты индексации ---
Invoke-IndexationUtility -msiPath $msiPath
# --- 10. Чистим EKP ---
Clear-FolderFull -FolderPath $ekpFolder
# --- 11. Чистим папку-источник (кроме .txt) ---
Clear-FolderExceptTxt -FolderPath $sourceFolder
Write-Host "Программа '$programName' успешно установлена!" -ForegroundColor Green
Write-Host "---------------------------------------------------" -ForegroundColor Gray
return $true
}
# =====================================================
# ОСНОВНОЙ ЦИКЛ
# =====================================================
Write-Host ""
Write-Host "=====================================================" -ForegroundColor Cyan
Write-Host "НАЧАЛО ОБРАБОТКИ ПАПОК" -ForegroundColor Cyan
Write-Host "=====================================================" -ForegroundColor Cyan
$successCount = 0
$totalCount = $programs.Count
foreach ($program in $programs) {
$folderName = $program.Folder
$programName = $program.Name
$sourceFolder = Join-Path -Path $rootFolder -ChildPath $folderName
if (Process-Program -folderName $folderName -programName $programName -sourceFolder $sourceFolder) {
$successCount++
}
}
# =====================================================
# ЗАВЕРШЕНИЕ
# =====================================================
Write-Host ""
Write-Host "=====================================================" -ForegroundColor Green
Write-Host "ОБРАБОТКА ВСЕХ ПАПОК ЗАВЕРШЕНА" -ForegroundColor Green
Write-Host "Успешно: $successCount из $totalCount" -ForegroundColor Green
Write-Host "=====================================================" -ForegroundColor Green
#exit 0
Read-Host "123"
if (-NOT ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")) {
Write-Host "Требуются права администратора. Запуск от имени администратора..." -ForegroundColor Yellow
Start-Process PowerShell -Verb RunAs -ArgumentList "-NoProfile -ExecutionPolicy Bypass -File `"$PSCommandPath`""
exit
}
# Путь к папке, где создается success.flag (должен совпадать с путем в основном скрипте)
$watcherPath = "D:\win10\Share\App" # или "Z:\App"
# Создаем наблюдатель
$watcher = New-Object System.IO.FileSystemWatcher
$watcher.Path = $watcherPath
$watcher.Filter = "success.flag"
$watcher.EnableRaisingEvents = $true
$watcher.IncludeSubdirectories = $false
# Действие при создании файла
$action = {
$path = $Event.SourceEventArgs.FullPath
$changeType = $Event.SourceEventArgs.ChangeType
$name = $Event.SourceEventArgs.Name
Write-Host "========================================" -ForegroundColor Cyan
Write-Host "СИГНАЛ ПОЛУЧЕН!" -ForegroundColor Green
Write-Host "Файл: $name" -ForegroundColor Yellow
Write-Host "Путь: $path" -ForegroundColor Yellow
Write-Host "Тип события: $changeType" -ForegroundColor Yellow
Write-Host "Время: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')" -ForegroundColor Yellow
# Небольшая задержка, чтобы файл гарантированно дописался
Start-Sleep -Milliseconds 500
if (Test-Path $path) {
# Показываем содержимое (если нужно)
try {
$content = Get-Content $path -Raw -ErrorAction Stop
Write-Host "Содержимое файла:" -ForegroundColor Gray
Write-Host $content -ForegroundColor Gray
} catch {
Write-Host "Не удалось прочитать содержимое: $($_.Exception.Message)" -ForegroundColor Red
}
$scriptPath = "D:\services\Рабочий стол\App2\123.ps1"
if (Test-Path $scriptPath) {
Write-Host "`nЗапуск скрипта: $scriptPath" -ForegroundColor Cyan
$exitCode = -1
try {
$proc = Start-Process powershell.exe -ArgumentList @(
"-NoProfile",
"-ExecutionPolicy", "Bypass",
"-File", "`"$scriptPath`""
) -Wait -PassThru -ErrorAction Stop
$exitCode = $proc.ExitCode
Write-Host "Скрипт 123.ps1 завершён с кодом: $exitCode" -ForegroundColor $(if ($exitCode -eq 0) { "Green" } else { "Red" })
}
catch {
Write-Host "ОШИБКА запуска 123.ps1: $($_.Exception.Message)" -ForegroundColor Red
$exitCode = -1
}
if ($exitCode -eq 0) {
Remove-Item $path -Force
Write-Host "✅ Обработка успешна, файл сигнала удалён" -ForegroundColor Green
} else {
Write-Host "❌ Скрипт завершился с кодом $exitCode, файл оставлен" -ForegroundColor Red
}
} else {
Write-Host "СКРИПТ НЕ НАЙДЕН: $scriptPath" -ForegroundColor Red
}
}
else {
Write-Host "ВНИМАНИЕ: Файл не найден!" -ForegroundColor Red
}
Write-Host "========================================" -ForegroundColor Cyan
Write-Host ""
}
# Регистрируем событие
$eventJob = Register-ObjectEvent -InputObject $watcher -EventName "Created" -Action $action
Write-Host "Наблюдатель запущен!" -ForegroundColor Cyan
Write-Host "Отслеживается папка: $watcherPath" -ForegroundColor Yellow
Write-Host "Ожидание файла: success.flag" -ForegroundColor Yellow
Write-Host ""
Write-Host "Для остановки нажмите Ctrl+C" -ForegroundColor Red
Write-Host ""
# Держим скрипт запущенным
try {
while ($true) {
Start-Sleep -Seconds 1
}
}
finally {
# Очистка при завершении
Unregister-Event -SubscriptionId $eventJob.Id
$watcher.Dispose()
Write-Host "`nНаблюдатель остановлен." -ForegroundColor Red
}