# ============================================================ # Skript ustanovki sertifikata dlya RDP signing # Zapusk: irm https://git.help-d.ru/installSSL | iex # ============================================================ # ========== НАСТРОЙКИ ========== $GiteaUrl = "https://git.help-d.ru" $RepoPath = "helmut/cert-deploy/raw/branch/main" $CertFileName = "Help-D_RDP.pfx" $CertPassword = "sj032ssa" $CertStorePath = "C:\tmp\cert" $ThumbprintFile = "$CertStorePath\thumbprint.txt" $RdpSign = "$env:SystemRoot\System32\rdpsign.exe" # =============================== # Фикс TLS для Windows Server (обязательно!) [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 -bor [Net.SecurityProtocolType]::Tls13 # Проверка прав администратора $IsAdmin = ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator") # Цвета и форматирование $HeaderColor = "Cyan" $SuccessColor = "Green" $ErrorColor = "Red" $WarningColor = "Yellow" $GrayColor = "Gray" function Show-Header { param([string]$Title) Clear-Host Write-Host "`n================================================" -ForegroundColor $HeaderColor Write-Host " $Title" -ForegroundColor $HeaderColor Write-Host "================================================`n" -ForegroundColor $HeaderColor } function Get-Thumbprint { if (Test-Path $ThumbprintFile) { return (Get-Content $ThumbprintFile -Raw).Trim() } # Пробуем найти установленный сертификат по субъекту $Cert = Get-ChildItem Cert:\LocalMachine\My | Where-Object { $_.Subject -like "*Help-D*" } | Select-Object -First 1 if ($Cert) { return $Cert.Thumbprint } return $null } function Install-Certificate { Show-Header " [1] УСТАНОВКА СЕРТИФИКАТА " if (-not $IsAdmin) { Write-Host "❌ Требуется запуск от имени Администратора" -ForegroundColor $ErrorColor Pause return } # Создание папки if (-not (Test-Path $CertStorePath)) { New-Item -ItemType Directory -Path $CertStorePath -Force | Out-Null } # Скачивание PFX $CertUrl = "$GiteaUrl/$RepoPath/$CertFileName" $CertPath = "$CertStorePath\$CertFileName" Write-Host "📥 Скачивание сертификата..." -ForegroundColor $GrayColor try { Invoke-WebRequest -Uri $CertUrl -OutFile $CertPath -ErrorAction Stop -UseBasicParsing Write-Host " ✅ Загружено: $CertFileName" -ForegroundColor $SuccessColor } catch { Write-Host " ❌ Ошибка загрузки: $_" -ForegroundColor $ErrorColor Pause return } # Установка Write-Host "`n🔐 Установка в хранилища..." -ForegroundColor $GrayColor $SecurePass = ConvertTo-SecureString -String $CertPassword -AsPlainText -Force try { $Cert = Import-PfxCertificate -FilePath $CertPath -CertStoreLocation Cert:\LocalMachine\My -Password $SecurePass -Exportable Import-PfxCertificate -FilePath $CertPath -CertStoreLocation Cert:\LocalMachine\Root -Password $SecurePass | Out-Null Import-PfxCertificate -FilePath $CertPath -CertStoreLocation Cert:\LocalMachine\TrustedPublisher -Password $SecurePass | Out-Null $Thumb = $Cert.Thumbprint $Thumb | Out-File -FilePath $ThumbprintFile -Encoding ASCII -Force Write-Host " ✅ LocalMachine\My" -ForegroundColor $SuccessColor Write-Host " ✅ LocalMachine\Root" -ForegroundColor $SuccessColor Write-Host " ✅ LocalMachine\TrustedPublisher" -ForegroundColor $SuccessColor Write-Host "`n📋 Отпечаток сохранён: $Thumb" -ForegroundColor $HeaderColor } catch { if ($_.Exception.Message -match "already exists") { $Cert = Get-ChildItem Cert:\LocalMachine\My | Where-Object { $_.Subject -like "*Help-D*" } | Select-Object -First 1 $Thumb = $Cert.Thumbprint if (-not (Test-Path $ThumbprintFile)) { $Thumb | Out-File -FilePath $ThumbprintFile -Encoding ASCII -Force } Write-Host " ℹ️ Сертификат уже установлен" -ForegroundColor $WarningColor Write-Host "📋 Отпечаток: $Thumb" -ForegroundColor $HeaderColor } else { Write-Host " ❌ Ошибка: $_" -ForegroundColor $ErrorColor Pause return } } # Очистка PFX Remove-Item $CertPath -Force -ErrorAction SilentlyContinue Write-Host "`n🗑️ PFX-файл удалён (безопасность)" -ForegroundColor $GrayColor Write-Host "`n✅ Установка завершена!" -ForegroundColor $SuccessColor Pause } function Sign-RdpFiles { param( [string[]]$Files, [string]$Description ) $Thumb = Get-Thumbprint if (-not $Thumb) { Write-Host "❌ Сертификат не найден. Сначала выполните пункт 1." -ForegroundColor $ErrorColor Pause return } if (-not (Test-Path $RdpSign)) { Write-Host "❌ rdpsign.exe не найден" -ForegroundColor $ErrorColor Pause return } Write-Host "`n$Description" -ForegroundColor $GrayColor Write-Host "🔑 Отпечаток: $Thumb`n" -ForegroundColor $GrayColor $Success = 0 $Failed = 0 foreach ($File in $Files) { $FileName = Split-Path $File -Leaf Write-Host " 📝 $FileName ... " -NoNewline -ForegroundColor $GrayColor # Пробуем SHA256 → SHA1 $Args = "/sha256", $Thumb, $File & $RdpSign @Args 2>&1 | Out-Null if ($LASTEXITCODE -ne 0) { $Args = "/sha1", $Thumb, $File & $RdpSign @Args 2>&1 | Out-Null } if ($LASTEXITCODE -eq 0) { Write-Host "✅" -ForegroundColor $SuccessColor $Success++ } else { Write-Host "❌" -ForegroundColor $ErrorColor $Failed++ } } Write-Host "`n📊 Результат: ✅ $Success | ❌ $Failed" -ForegroundColor $HeaderColor Pause } function Sign-AllDesktopRdp { Show-Header " [2] ПОДПИСАТЬ ВСЕ RDP НА РАБОЧИХ СТОЛАХ " $Files = @() # Рабочий стол текущего пользователя $CurrentUserDesktop = [Environment]::GetFolderPath("Desktop") if (Test-Path $CurrentUserDesktop) { $Files += Get-ChildItem -Path $CurrentUserDesktop -Filter "*.rdp" -File | Select-Object -ExpandProperty FullName } # Рабочие столы всех пользователей (Public + профили) $PublicDesktop = "C:\Users\Public\Desktop" if (Test-Path $PublicDesktop) { $Files += Get-ChildItem -Path $PublicDesktop -Filter "*.rdp" -File | Select-Object -ExpandProperty FullName } # Сканируем C:\Users\*\Desktop $UserFolders = Get-ChildItem "C:\Users" -Directory -ErrorAction SilentlyContinue | Where-Object { $_.Name -notmatch "Public|Default|All Users" } foreach ($User in $UserFolders) { $UserDesktop = "$($User.FullName)\Desktop" if (Test-Path $UserDesktop) { $Files += Get-ChildItem -Path $UserDesktop -Filter "*.rdp" -File -ErrorAction SilentlyContinue | Select-Object -ExpandProperty FullName } } # RemoteApp: Packaged Programs $RemoteAppPath = "C:\Program Files\Packaged Programs" if (Test-Path $RemoteAppPath) { $Files += Get-ChildItem -Path $RemoteAppPath -Filter "*.rdp" -File -Recurse -ErrorAction SilentlyContinue | Select-Object -ExpandProperty FullName # Также ищем .msc файлы для RemoteApp (если нужно) $Files += Get-ChildItem -Path $RemoteAppPath -Filter "*.msc" -File -Recurse -ErrorAction SilentlyContinue | Select-Object -ExpandProperty FullName } # Убираем дубликаты $Files = $Files | Select-Object -Unique if ($Files.Count -eq 0) { Write-Host "⚠️ RDP-файлы не найдены" -ForegroundColor $WarningColor Pause return } Write-Host "📁 Найдено файлов: $($Files.Count)" -ForegroundColor $GrayColor $Confirm = Read-Host "Подписать все? (y/n)" if ($Confirm -ne "y") { return } Sign-RdpFiles -Files $Files -Description "🚀 Начало пакетного подписания..." } function Sign-SelectedRdp { Show-Header " [3] ПОДПИСАТЬ ВЫБРАННЫЙ RDP " Add-Type -AssemblyName System.Windows.Forms $ofd = New-Object System.Windows.Forms.OpenFileDialog $ofd.Title = "Выберите RDP файл для подписания" $ofd.Filter = "RDP Files|*.rdp|All Files|*.*" $ofd.InitialDirectory = [Environment]::GetFolderPath("Desktop") if ($ofd.ShowDialog() -ne 'OK') { return } Sign-RdpFiles -Files @($ofd.FileName) -Description "📝 Подписание файла:" } function Remove-Certificate { Show-Header " [4] УДАЛИТЬ СЕРТИФИКАТ ИЗ СИСТЕМЫ " if (-not $IsAdmin) { Write-Host "❌ Требуется запуск от имени Администратора" -ForegroundColor $ErrorColor Pause return } $Thumb = Get-Thumbprint if (-not $Thumb) { Write-Host "⚠️ Сертификат не найден в системе" -ForegroundColor $WarningColor Pause return } Write-Host "🔍 Найден сертификат:" -ForegroundColor $GrayColor $Cert = Get-ChildItem Cert:\LocalMachine\My | Where-Object { $_.Thumbprint -eq $Thumb } if ($Cert) { Write-Host " Subject: $($Cert.Subject)" -ForegroundColor $GrayColor Write-Host " Thumbprint: $($Cert.Thumbprint)" -ForegroundColor $GrayColor } $Confirm = Read-Host "`nУдалить из Root, TrustedPublisher и My? (y/n)" if ($Confirm -ne "y") { return } $Stores = "Cert:\LocalMachine\Root", "Cert:\LocalMachine\TrustedPublisher", "Cert:\LocalMachine\My" foreach ($Store in $Stores) { $Cert = Get-ChildItem $Store -ErrorAction SilentlyContinue | Where-Object { $_.Thumbprint -eq $Thumb } if ($Cert) { Remove-Item $Cert.PSPath -Force -ErrorAction SilentlyContinue Write-Host " ✅ Удалено из $Store" -ForegroundColor $SuccessColor } } # Удаляем файл с отпечатком if (Test-Path $ThumbprintFile) { Remove-Item $ThumbprintFile -Force Write-Host " ✅ Удалён файл отпечатка" -ForegroundColor $SuccessColor } Write-Host "`n✅ Удаление завершено" -ForegroundColor $SuccessColor Pause } function Check-Certificate { Show-Header " [5] ПРОВЕРКА СТАТУСА СЕРТИФИКАТА " $Thumb = Get-Thumbprint Write-Host "📋 Информация:" -ForegroundColor $HeaderColor Write-Host " Отпечаток (из файла): $($Thumb ?? 'не найден')" -ForegroundColor $GrayColor $Stores = @{ "LocalMachine\My" = "Приватный ключ (для подписи)" "LocalMachine\Root" = "Доверенные корневые центры" "LocalMachine\TrustedPublisher" = "Доверенные издатели (RDP)" } foreach ($StoreName in $Stores.Keys) { $Store = "Cert:\LocalMachine\$StoreName" $Cert = Get-ChildItem $Store -ErrorAction SilentlyContinue | Where-Object { $_.Thumbprint -eq $Thumb } $Status = if ($Cert) { "✅ Установлен" } else { "❌ Не найден" } $Color = if ($Cert) { $SuccessColor } else { $ErrorColor } Write-Host " $($Stores[$StoreName]): " -NoNewline Write-Host "$Status" -ForegroundColor $Color } # Проверка rdpsign.exe Write-Host "`n🔧 Инструменты:" -ForegroundColor $HeaderColor if (Test-Path $RdpSign) { Write-Host " rdpsign.exe: ✅ Найден" -ForegroundColor $SuccessColor } else { Write-Host " rdpsign.exe: ❌ Не найден" -ForegroundColor $ErrorColor } Write-Host "`n💡 Подсказка: Для отображения «Проверенный издатель» в RDP-клиенте" -ForegroundColor $GrayColor Write-Host " сертификат должен быть в Root И в TrustedPublisher" -ForegroundColor $GrayColor Pause } # ========== ГЛАВНОЕ МЕНЮ ========== do { Show-Header " RDP CERTIFICATE MANAGER " Write-Host " [1] Установить сертификат" -ForegroundColor $HeaderColor Write-Host " [2] Подписать все RDP (рабочие столы + RemoteApp)" -ForegroundColor $HeaderColor Write-Host " [3] Подписать выбранный RDP" -ForegroundColor $HeaderColor Write-Host " [4] Удалить сертификат из системы" -ForegroundColor $HeaderColor Write-Host " [5] Проверка статуса сертификата" -ForegroundColor $HeaderColor Write-Host " [0] Выход" -ForegroundColor $WarningColor Write-Host "`n------------------------------------------------" -ForegroundColor $GrayColor $Choice = Read-Host "Выберите действие (0-5)" switch ($Choice) { "1" { Install-Certificate } "2" { Sign-AllDesktopRdp } "3" { Sign-SelectedRdp } "4" { Remove-Certificate } "5" { Check-Certificate } "0" { Write-Host "`n👋 Выход. Удачи!" -ForegroundColor $SuccessColor; Start-Sleep -Seconds 1 } default { Write-Host "`n⚠️ Неверный выбор" -ForegroundColor $WarningColor; Start-Sleep -Seconds 1 } } } while ($Choice -ne "0")