ssl/installSSL.ps1

376 lines
17 KiB
PowerShell
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# ============================================================
# RDP Certificate Manager - Menu Script (PS 5.1 Compatible)
# Zapusk: irm https://git.help-d.ru/installSSL | iex
# ============================================================
# ========== НАСТРОЙКИ ==========
$GiteaUrl = "https://git.help-d.ru"
$RepoPath = "helmut/ssl.git//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
}
$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
}
}
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
$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
}
$PublicDesktop = "C:\Users\Public\Desktop"
if (Test-Path $PublicDesktop) {
$Files += Get-ChildItem -Path $PublicDesktop -Filter "*.rdp" -File | Select-Object -ExpandProperty FullName
}
$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
}
}
$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
$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] ПРОВЕРКА СТАТУСА СЕРТИФИКАТА "
Write-Host "📋 Диагностика:" -ForegroundColor $HeaderColor
# 1. Проверяем, есть ли подписанные RDP на рабочем столе
$Desktop = [Environment]::GetFolderPath("Desktop")
$RdpFiles = Get-ChildItem -Path $Desktop -Filter "*.rdp" -File -ErrorAction SilentlyContinue
$RdpThumb = $null
if ($RdpFiles.Count -gt 0) {
# Берём первый RDP и читаем его подпись
$FirstRdp = $RdpFiles[0].FullName
$Content = Get-Content $FirstRdp -Encoding UTF8 -ErrorAction SilentlyContinue
$SigLine = $Content | Where-Object { $_ -match "^signature:s:" }
if ($SigLine) {
# Извлекаем отпечаток из подписи (упрощённо: берём первые 40 символов после префикса)
$RawSig = $SigLine -replace "signature:s:",""
# В реальной подписи это баз64-блок, но для проверки нам хватит поиска по субъекту
$RdpThumb = "из файла $(Split-Path $FirstRdp -Leaf)"
Write-Host " 📄 Найден подписанный RDP: $(Split-Path $FirstRdp -Leaf)" -ForegroundColor $GrayColor
}
}
if (-not $RdpThumb) {
Write-Host " ⚠️ Подписанные RDP не найдены на рабочем столе" -ForegroundColor $WarningColor
}
# 2. Ищем сертификаты по имени издателя (как в твоём рабочем скрипте)
$SearchPattern = "*Help-D*" # <-- Поменяй на своё имя, если нужно
Write-Host "`n🔍 Поиск в хранилищах (по субъекту: $SearchPattern):" -ForegroundColor $GrayColor
$Stores = @{
"Cert:\LocalMachine\My" = "My (приватный ключ)"
"Cert:\LocalMachine\Root" = "Root (доверенные центры)"
"Cert:\LocalMachine\TrustedPublisher" = "TrustedPublisher (издатели RDP)"
}
$FoundCerts = @{}
foreach ($StorePath in $Stores.Keys) {
$Certs = Get-ChildItem $StorePath -ErrorAction SilentlyContinue | Where-Object { $_.Subject -like $SearchPattern }
$FoundCerts[$StorePath] = $Certs
$Count = $Certs.Count
$Status = if ($Count -gt 0) { "✅ Найден ($Count шт.)" } else { "Не найден" }
$Color = if ($Count -gt 0) { $SuccessColor } else { $ErrorColor }
Write-Host " $($Stores[$StorePath]): " -NoNewline
Write-Host "$Status" -ForegroundColor $Color
# Показываем отпечатки найденных
foreach ($Cert in $Certs) {
Write-Host "$($Cert.Thumbprint)" -ForegroundColor $GrayColor
}
}
# 3. Сверка: есть ли отпечаток из RDP в доверенных хранилищах
Write-Host "`n🔗 Сверка доверия:" -ForegroundColor $HeaderColor
if ($RdpThumb -and $FoundCerts["Cert:\LocalMachine\Root"] -and $FoundCerts["Cert:\LocalMachine\TrustedPublisher"]) {
# Если в обоих хранилищах есть сертификаты с нужным именем — скорее всего, всё ок
$RootThumb = $FoundCerts["Cert:\LocalMachine\Root"][0].Thumbprint
$TrustedThumb = $FoundCerts["Cert:\LocalMachine\TrustedPublisher"][0].Thumbprint
if ($RootThumb -eq $TrustedThumb) {
Write-Host " ✅ Сертификат в Root и TrustedPublisher совпадает" -ForegroundColor $SuccessColor
Write-Host " ✅ RDP-клиент покажет «Проверенный издатель»" -ForegroundColor $SuccessColor
} else {
Write-Host " ⚠️ В Root и TrustedPublisher разные сертификаты" -ForegroundColor $WarningColor
Write-Host " Root: $RootThumb" -ForegroundColor $GrayColor
Write-Host " TrustedPublisher: $TrustedThumb" -ForegroundColor $GrayColor
}
} elseif (-not $FoundCerts["Cert:\LocalMachine\Root"] -or -not $FoundCerts["Cert:\LocalMachine\TrustedPublisher"]) {
Write-Host " ❌ Сертификат должен быть в Root И в TrustedPublisher" -ForegroundColor $ErrorColor
Write-Host " Запусти пункт [1] для установки" -ForegroundColor $GrayColor
}
# 4. Проверка rdpsign.exe
Write-Host "`n🔧 Инструменты:" -ForegroundColor $HeaderColor
if (Test-Path $RdpSign) {
Write-Host " rdpsign.exe: ✅ Найден ($RdpSign)" -ForegroundColor $SuccessColor
} else {
Write-Host " rdpsign.exe: ❌ Не найден" -ForegroundColor $ErrorColor
}
Write-Host "`n💡 Подсказка:" -ForegroundColor $GrayColor
Write-Host " Если RDP показывает «Неизвестный издатель»:" -ForegroundColor $GrayColor
Write-Host " 1. Убедись, что сертификат установлен в Root и TrustedPublisher" -ForegroundColor $GrayColor
Write-Host " 2. Перезапусти Remote Desktop клиент" -ForegroundColor $GrayColor
Write-Host " 3. Если не помогло — перезагрузи компьютер" -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")