334 lines
14 KiB
PowerShell
334 lines
14 KiB
PowerShell
# ============================================================
|
||
# 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") |