Dateien nach "/" hochladen
This commit is contained in:
+354
-48
@@ -35,6 +35,23 @@ $HealthFileName = "Test-SMTPGraphRelay.ps1"
|
||||
$RenewFileName = "Renew-SMTPGraphRelayCertificate.ps1"
|
||||
$ConfigFileName = "config.json"
|
||||
|
||||
# Zentrales Gitea-Repository / Updatequelle
|
||||
$RepoBaseUrl = "https://me-gitea.maieredv.cloud/MAIEREDV/SMTPGraphRelay"
|
||||
$RemoteVersionUrl = "$RepoBaseUrl/raw/branch/main/version.json"
|
||||
$RemoteArchiveUrl = "$RepoBaseUrl/archive/main.zip"
|
||||
$RemoteRelayUrl = "$RepoBaseUrl/raw/branch/main/SMTPGraphRelay.ps1"
|
||||
|
||||
# Dateien, die ein Update verändern darf.
|
||||
# config.json, Queue, Logs und sonstige lokale Daten sind absichtlich NICHT enthalten.
|
||||
$ManagedReleaseFiles = @(
|
||||
"SMTPGraphRelay.ps1",
|
||||
"Test-SMTPGraphRelay.ps1",
|
||||
"Renew-SMTPGraphRelayCertificate.ps1",
|
||||
"Setup-SMTPGraphRelay.ps1",
|
||||
"version.json",
|
||||
"README.md"
|
||||
)
|
||||
|
||||
function Write-Title {
|
||||
param([string]$Text)
|
||||
Write-Host ""
|
||||
@@ -513,6 +530,166 @@ function Test-NoGlobalMailSend {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function Enable-Tls12 {
|
||||
try {
|
||||
[Net.ServicePointManager]::SecurityProtocol = `
|
||||
[Net.ServicePointManager]::SecurityProtocol -bor `
|
||||
[Net.SecurityProtocolType]::Tls12
|
||||
} catch {}
|
||||
}
|
||||
|
||||
function Get-RemoteVersion {
|
||||
Enable-Tls12
|
||||
|
||||
$tempFile = Join-Path $env:TEMP ("SMTPGraphRelay-version-{0}.json" -f [guid]::NewGuid().ToString("N"))
|
||||
|
||||
try {
|
||||
Invoke-WebRequest `
|
||||
-Uri $RemoteVersionUrl `
|
||||
-OutFile $tempFile `
|
||||
-UseBasicParsing `
|
||||
-TimeoutSec 20 `
|
||||
-ErrorAction Stop
|
||||
|
||||
$remote = Get-Content -LiteralPath $tempFile -Raw -Encoding UTF8 | ConvertFrom-Json
|
||||
|
||||
if (-not $remote.Version) {
|
||||
throw "Remote version.json enthält keine Version."
|
||||
}
|
||||
|
||||
return $remote
|
||||
}
|
||||
finally {
|
||||
Remove-Item -LiteralPath $tempFile -Force -ErrorAction SilentlyContinue
|
||||
}
|
||||
}
|
||||
|
||||
function Compare-RelayVersions {
|
||||
param(
|
||||
[Parameter(Mandatory)][string]$Installed,
|
||||
[Parameter(Mandatory)][string]$Remote
|
||||
)
|
||||
|
||||
try {
|
||||
$installedVersion = [version]$Installed
|
||||
$remoteVersion = [version]$Remote
|
||||
|
||||
if ($remoteVersion -gt $installedVersion) { return 1 }
|
||||
if ($remoteVersion -lt $installedVersion) { return -1 }
|
||||
return 0
|
||||
}
|
||||
catch {
|
||||
throw "Versionsvergleich fehlgeschlagen: installiert='$Installed', remote='$Remote'."
|
||||
}
|
||||
}
|
||||
|
||||
function Find-ExtractedReleaseRoot {
|
||||
param(
|
||||
[Parameter(Mandatory)][string]$ExtractPath
|
||||
)
|
||||
|
||||
# Gitea kann beim Archiv einen zusätzlichen Root-Ordner erzeugen.
|
||||
# Daher suchen wir nach der Kombination aus Relay + version.json statt
|
||||
# einen konkreten Archivordnernamen vorauszusetzen.
|
||||
$relayFiles = Get-ChildItem `
|
||||
-LiteralPath $ExtractPath `
|
||||
-Recurse `
|
||||
-File `
|
||||
-Filter $RelayFileName `
|
||||
-ErrorAction SilentlyContinue
|
||||
|
||||
foreach ($relay in $relayFiles) {
|
||||
$candidate = $relay.Directory.FullName
|
||||
if (Test-Path -LiteralPath (Join-Path $candidate "version.json")) {
|
||||
return $candidate
|
||||
}
|
||||
}
|
||||
|
||||
throw "Im heruntergeladenen Archiv wurde kein gültiges SMTPGraphRelay-Release gefunden."
|
||||
}
|
||||
|
||||
function Backup-ManagedFiles {
|
||||
param(
|
||||
[Parameter(Mandatory)][string]$TargetPath
|
||||
)
|
||||
|
||||
$backupRoot = Join-Path $TargetPath "backup"
|
||||
$backupPath = Join-Path $backupRoot (Get-Date -Format "yyyyMMdd-HHmmss")
|
||||
|
||||
New-Item -ItemType Directory -Path $backupPath -Force | Out-Null
|
||||
|
||||
foreach ($name in $ManagedReleaseFiles) {
|
||||
$source = Join-Path $TargetPath $name
|
||||
|
||||
if (Test-Path -LiteralPath $source) {
|
||||
Copy-Item -LiteralPath $source -Destination (Join-Path $backupPath $name) -Force
|
||||
}
|
||||
}
|
||||
|
||||
return $backupPath
|
||||
}
|
||||
|
||||
function Restore-ManagedFiles {
|
||||
param(
|
||||
[Parameter(Mandatory)][string]$BackupPath,
|
||||
[Parameter(Mandatory)][string]$TargetPath
|
||||
)
|
||||
|
||||
foreach ($name in $ManagedReleaseFiles) {
|
||||
$backupFile = Join-Path $BackupPath $name
|
||||
$targetFile = Join-Path $TargetPath $name
|
||||
|
||||
if (Test-Path -LiteralPath $backupFile) {
|
||||
Copy-Item -LiteralPath $backupFile -Destination $targetFile -Force
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function Install-ExtractedRelease {
|
||||
param(
|
||||
[Parameter(Mandatory)][string]$ReleaseRoot,
|
||||
[Parameter(Mandatory)][string]$TargetPath
|
||||
)
|
||||
|
||||
$required = @(
|
||||
"SMTPGraphRelay.ps1",
|
||||
"version.json"
|
||||
)
|
||||
|
||||
foreach ($name in $required) {
|
||||
if (-not (Test-Path -LiteralPath (Join-Path $ReleaseRoot $name))) {
|
||||
throw "Updatepaket ist unvollständig: '$name' fehlt."
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($name in $ManagedReleaseFiles) {
|
||||
$source = Join-Path $ReleaseRoot $name
|
||||
|
||||
if (Test-Path -LiteralPath $source) {
|
||||
Copy-Item -LiteralPath $source -Destination (Join-Path $TargetPath $name) -Force
|
||||
Write-Ok "Aktualisiert: $name"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function Invoke-PostUpdateHealthCheck {
|
||||
param(
|
||||
[Parameter(Mandatory)][string]$TargetPath
|
||||
)
|
||||
|
||||
$health = Join-Path $TargetPath $HealthFileName
|
||||
|
||||
if (-not (Test-Path -LiteralPath $health)) {
|
||||
Write-Warn "Health Check ist nicht installiert; automatische Nachprüfung entfällt."
|
||||
return 0
|
||||
}
|
||||
|
||||
Write-Info "Starte Health Check nach dem Update..."
|
||||
& $health -ConfigPath (Join-Path $TargetPath $ConfigFileName)
|
||||
return $LASTEXITCODE
|
||||
}
|
||||
|
||||
function Install-New {
|
||||
Write-Title "SMTPGraphRelay - Neuinstallation"
|
||||
|
||||
@@ -670,6 +847,32 @@ function Install-New {
|
||||
elseif (Test-Path -LiteralPath (Join-Path $InstallPath $RelayFileName)) {
|
||||
Write-Warn "Installierte Version unbekannt (keine version.json)."
|
||||
}
|
||||
|
||||
try {
|
||||
$remoteVersionInfo = Get-RemoteVersion
|
||||
if ($remoteVersionInfo -and $remoteVersionInfo.Version) {
|
||||
Write-Host "Remote (main): $($remoteVersionInfo.Version)"
|
||||
|
||||
if ($installedVersion -and $installedVersion.Version) {
|
||||
$cmp = Compare-RelayVersions `
|
||||
-Installed ([string]$installedVersion.Version) `
|
||||
-Remote ([string]$remoteVersionInfo.Version)
|
||||
|
||||
if ($cmp -gt 0) {
|
||||
Write-Warn "Update verfügbar."
|
||||
}
|
||||
elseif ($cmp -eq 0) {
|
||||
Write-Ok "Version ist aktuell."
|
||||
}
|
||||
else {
|
||||
Write-Warn "Lokale Version ist neuer als Repository-main."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch {
|
||||
Write-Warn "Remote-Version konnte nicht geprüft werden."
|
||||
}
|
||||
Write-Host "Client ID: $($app.AppId)"
|
||||
Write-Host "Tenant ID: $tenantId"
|
||||
Write-Host "Sender: $senderMailbox"
|
||||
@@ -725,7 +928,7 @@ function Repair-Installation {
|
||||
}
|
||||
|
||||
function Update-Relay {
|
||||
Write-Title "SMTPGraphRelay - Update"
|
||||
Write-Title "SMTPGraphRelay - Online Update"
|
||||
|
||||
$config = Get-RelayConfig -TargetPath $InstallPath
|
||||
if (-not $config) {
|
||||
@@ -734,76 +937,182 @@ function Update-Relay {
|
||||
return
|
||||
}
|
||||
|
||||
$packageVersion = Get-PackageVersion
|
||||
$installedVersion = Get-InstalledVersion -TargetPath $InstallPath
|
||||
$installedVersionInfo = Get-InstalledVersion -TargetPath $InstallPath
|
||||
$installedVersion = $null
|
||||
|
||||
if ($packageVersion -and $packageVersion.Version) {
|
||||
Write-Info "Paketversion: $($packageVersion.Version)"
|
||||
if ($installedVersionInfo -and $installedVersionInfo.Version) {
|
||||
$installedVersion = [string]$installedVersionInfo.Version
|
||||
Write-Info "Installierte Version: $installedVersion"
|
||||
}
|
||||
else {
|
||||
Write-Warn "Keine installierte version.json gefunden."
|
||||
$installedVersion = Read-Host "Installierte Version manuell eingeben (z.B. 1.5.0)"
|
||||
if ([string]::IsNullOrWhiteSpace($installedVersion)) {
|
||||
Write-Fail "Ohne lokale Versionsinformation kann kein sicheres Online-Update durchgeführt werden."
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if ($installedVersion -and $installedVersion.Version) {
|
||||
Write-Info "Installierte Version: $($installedVersion.Version)"
|
||||
Write-Info "Prüfe Gitea auf neue Version..."
|
||||
Write-Info "Repository: $RepoBaseUrl"
|
||||
|
||||
try {
|
||||
$pkgVer = [version]$packageVersion.Version
|
||||
$instVer = [version]$installedVersion.Version
|
||||
$remoteInfo = Get-RemoteVersion
|
||||
}
|
||||
catch {
|
||||
Write-Fail "Remote-Version konnte nicht geladen werden: $($_.Exception.Message)"
|
||||
return
|
||||
}
|
||||
|
||||
if ($pkgVer -lt $instVer) {
|
||||
Write-Warn "Das Paket ist älter als die installierte Version."
|
||||
if (-not (Confirm-Yes "Downgrade trotzdem durchführen?")) {
|
||||
$remoteVersion = [string]$remoteInfo.Version
|
||||
Write-Ok "Remote-Version: $remoteVersion"
|
||||
|
||||
try {
|
||||
$comparison = Compare-RelayVersions -Installed $installedVersion -Remote $remoteVersion
|
||||
}
|
||||
catch {
|
||||
Write-Fail $_.Exception.Message
|
||||
return
|
||||
}
|
||||
|
||||
if ($comparison -eq 0) {
|
||||
Write-Ok "SMTPGraphRelay ist bereits aktuell ($installedVersion)."
|
||||
return
|
||||
}
|
||||
|
||||
if ($comparison -lt 0) {
|
||||
Write-Warn "Die installierte Version ($installedVersion) ist neuer als main ($remoteVersion)."
|
||||
if (-not (Confirm-Yes "Downgrade auf $remoteVersion durchführen?")) {
|
||||
return
|
||||
}
|
||||
}
|
||||
elseif ($pkgVer -eq $instVer) {
|
||||
Write-Warn "Paket- und installierte Version sind identisch."
|
||||
if (-not (Confirm-Yes "Version trotzdem erneut einspielen?")) {
|
||||
else {
|
||||
Write-Host ""
|
||||
Write-Host "Update verfügbar:" -ForegroundColor Green
|
||||
Write-Host " Installiert: $installedVersion"
|
||||
Write-Host " Neu: $remoteVersion" -ForegroundColor Yellow
|
||||
Write-Host ""
|
||||
|
||||
if (-not (Confirm-Yes "Update auf $remoteVersion installieren?")) {
|
||||
return
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
Write-Warn "Versionsvergleich konnte nicht durchgeführt werden."
|
||||
}
|
||||
}
|
||||
|
||||
$sourceRelay = Get-SourceFile -Name $RelayFileName
|
||||
if (-not $sourceRelay) {
|
||||
Write-Fail "Kein neues '$RelayFileName' neben dem Installer gefunden."
|
||||
return
|
||||
Enable-Tls12
|
||||
|
||||
$updateRoot = Join-Path $env:TEMP ("SMTPGraphRelay-update-{0}" -f [guid]::NewGuid().ToString("N"))
|
||||
$archivePath = Join-Path $updateRoot "main.zip"
|
||||
$extractPath = Join-Path $updateRoot "extract"
|
||||
|
||||
New-Item -ItemType Directory -Path $updateRoot -Force | Out-Null
|
||||
New-Item -ItemType Directory -Path $extractPath -Force | Out-Null
|
||||
|
||||
$backupPath = $null
|
||||
$taskWasRunning = $false
|
||||
|
||||
try {
|
||||
Write-Info "Lade Repository-Archiv..."
|
||||
Invoke-WebRequest `
|
||||
-Uri $RemoteArchiveUrl `
|
||||
-OutFile $archivePath `
|
||||
-UseBasicParsing `
|
||||
-TimeoutSec 120 `
|
||||
-ErrorAction Stop
|
||||
|
||||
if (-not (Test-Path -LiteralPath $archivePath)) {
|
||||
throw "Download des Updatearchivs fehlgeschlagen."
|
||||
}
|
||||
|
||||
Write-Ok "Archiv heruntergeladen."
|
||||
|
||||
Expand-Archive `
|
||||
-LiteralPath $archivePath `
|
||||
-DestinationPath $extractPath `
|
||||
-Force
|
||||
|
||||
$releaseRoot = Find-ExtractedReleaseRoot -ExtractPath $extractPath
|
||||
Write-Ok "Release im Archiv gefunden: $releaseRoot"
|
||||
|
||||
$downloadedVersionInfo = Get-Content `
|
||||
-LiteralPath (Join-Path $releaseRoot "version.json") `
|
||||
-Raw `
|
||||
-Encoding UTF8 | ConvertFrom-Json
|
||||
|
||||
if (-not $downloadedVersionInfo.Version) {
|
||||
throw "version.json im Archiv enthält keine Version."
|
||||
}
|
||||
|
||||
if ([string]$downloadedVersionInfo.Version -ne $remoteVersion) {
|
||||
throw "Versionskonflikt: version.json-URL meldet $remoteVersion, Archiv enthält $($downloadedVersionInfo.Version)."
|
||||
}
|
||||
|
||||
$task = Get-ScheduledTask -TaskName $TaskName -ErrorAction SilentlyContinue
|
||||
if ($task -and $task.State -eq "Running") {
|
||||
$taskWasRunning = $true
|
||||
}
|
||||
|
||||
Write-Info "Erstelle Backup der verwalteten Programmdateien..."
|
||||
$backupPath = Backup-ManagedFiles -TargetPath $InstallPath
|
||||
Write-Ok "Backup: $backupPath"
|
||||
|
||||
Stop-RelayTask
|
||||
|
||||
$installedRelay = Join-Path $InstallPath $RelayFileName
|
||||
if (Test-Path -LiteralPath $installedRelay) {
|
||||
$backup = Join-Path $InstallPath ("SMTPGraphRelay-backup-{0}.ps1" -f (Get-Date -Format "yyyyMMdd-HHmmss"))
|
||||
Copy-Item -LiteralPath $installedRelay -Destination $backup -Force
|
||||
Write-Ok "Backup erstellt: $backup"
|
||||
}
|
||||
Write-Info "Installiere Release $remoteVersion..."
|
||||
Install-ExtractedRelease `
|
||||
-ReleaseRoot $releaseRoot `
|
||||
-TargetPath $InstallPath
|
||||
|
||||
Copy-ProgramFiles -TargetPath $InstallPath -RequireRelay
|
||||
Ensure-Directories -TargetPath $InstallPath
|
||||
Ensure-FirewallRule -Port ([int]$config.Smtp.Port)
|
||||
Ensure-ScheduledTask -TargetPath $InstallPath
|
||||
|
||||
Start-RelayTask
|
||||
|
||||
$health = Join-Path $InstallPath $HealthFileName
|
||||
if (Test-Path -LiteralPath $health) {
|
||||
Write-Info "Starte Health Check..."
|
||||
& $health -ConfigPath (Join-Path $InstallPath $ConfigFileName)
|
||||
$healthExit = $LASTEXITCODE
|
||||
$healthExit = Invoke-PostUpdateHealthCheck -TargetPath $InstallPath
|
||||
|
||||
if ($healthExit -eq 0) {
|
||||
Write-Ok "Update-Health-Check erfolgreich."
|
||||
if ($healthExit -ge 2) {
|
||||
throw "Health Check nach Update meldet FEHLER (ExitCode $healthExit)."
|
||||
}
|
||||
elseif ($healthExit -eq 1) {
|
||||
Write-Warn "Update abgeschlossen, Health Check enthält Warnungen."
|
||||
|
||||
if ($healthExit -eq 1) {
|
||||
Write-Warn "Update erfolgreich, Health Check enthält Warnungen."
|
||||
}
|
||||
else {
|
||||
Write-Fail "Update eingespielt, Health Check meldet Fehler. Backup liegt im Installationsordner."
|
||||
}
|
||||
Write-Ok "Health Check nach Update erfolgreich."
|
||||
}
|
||||
|
||||
Write-Title "Update abgeschlossen"
|
||||
Write-Title "Online Update abgeschlossen"
|
||||
Write-Host "Vorher: $installedVersion"
|
||||
Write-Host "Jetzt: $remoteVersion" -ForegroundColor Green
|
||||
Write-Host "Backup: $backupPath"
|
||||
}
|
||||
catch {
|
||||
Write-Host ""
|
||||
Write-Fail "Update fehlgeschlagen: $($_.Exception.Message)"
|
||||
|
||||
if ($backupPath -and (Test-Path -LiteralPath $backupPath)) {
|
||||
Write-Warn "Automatischer Rollback wird durchgeführt..."
|
||||
|
||||
try {
|
||||
Stop-RelayTask
|
||||
Restore-ManagedFiles `
|
||||
-BackupPath $backupPath `
|
||||
-TargetPath $InstallPath
|
||||
|
||||
Ensure-ScheduledTask -TargetPath $InstallPath
|
||||
Start-RelayTask
|
||||
|
||||
Write-Ok "Rollback abgeschlossen."
|
||||
}
|
||||
catch {
|
||||
Write-Fail "Rollback fehlgeschlagen: $($_.Exception.Message)"
|
||||
Write-Warn "Backup liegt unter: $backupPath"
|
||||
}
|
||||
}
|
||||
}
|
||||
finally {
|
||||
Remove-Item -LiteralPath $updateRoot -Recurse -Force -ErrorAction SilentlyContinue
|
||||
}
|
||||
}
|
||||
|
||||
function Verify-CloudRbac {
|
||||
@@ -1032,20 +1341,17 @@ function Show-Menu {
|
||||
Write-Title "SMTPGraphRelay - Installer / Repair / Update"
|
||||
Write-Host "Installationspfad: $InstallPath" -ForegroundColor DarkGray
|
||||
|
||||
$packageVersion = Get-PackageVersion
|
||||
$installedVersion = Get-InstalledVersion -TargetPath $InstallPath
|
||||
|
||||
if ($packageVersion -and $packageVersion.Version) {
|
||||
Write-Host "Paketversion: $($packageVersion.Version)" -ForegroundColor DarkGray
|
||||
}
|
||||
|
||||
if ($installedVersion -and $installedVersion.Version) {
|
||||
Write-Host "Installiert: $($installedVersion.Version)" -ForegroundColor DarkGray
|
||||
}
|
||||
|
||||
Write-Host "Updatequelle: Gitea / main" -ForegroundColor DarkGray
|
||||
Write-Host ""
|
||||
Write-Host " [1] Neuinstallation"
|
||||
Write-Host " [2] Installation reparieren"
|
||||
Write-Host " [3] Relay aktualisieren"
|
||||
Write-Host " [3] Nach Online-Updates suchen"
|
||||
Write-Host " [4] Entra / Exchange RBAC prüfen"
|
||||
Write-Host " [5] Zertifikat erneuern"
|
||||
Write-Host " [6] Health Check ausführen"
|
||||
|
||||
Reference in New Issue
Block a user