Setup-SMTPGraphRelay.ps1 aktualisiert
This commit is contained in:
1 parent
c7d547a45f
commit
722a80f613
1 file changed
+241
-32
+241
-32
@@ -1459,7 +1459,7 @@ function Get-FailedQueueEntries {
|
|||||||
MetaPath = $metaPath
|
MetaPath = $metaPath
|
||||||
SizeKB = [Math]::Round($file.Length / 1KB, 1)
|
SizeKB = [Math]::Round($file.Length / 1KB, 1)
|
||||||
FailedSince = $file.LastWriteTime
|
FailedSince = $file.LastWriteTime
|
||||||
RetryCount = if ($meta -and $meta.RetryCount -ne$null) { [int]$meta.RetryCount } else {$null }
|
RetryCount = if ($meta -and $meta.RetryCount -ne $null) { [int]$meta.RetryCount } else { $null }
|
||||||
From = if ($meta) { [string]$meta.EnvelopeFrom } else { "" }
|
From = if ($meta) { [string]$meta.EnvelopeFrom } else { "" }
|
||||||
Recipients = if ($meta) { (@($meta.EnvelopeRecipients) -join ", ") } else { "" }
|
Recipients = if ($meta) { (@($meta.EnvelopeRecipients) -join ", ") } else { "" }
|
||||||
LastStatusCode = if ($meta) { [string]$meta.LastStatusCode } else { "" }
|
LastStatusCode = if ($meta) { [string]$meta.LastStatusCode } else { "" }
|
||||||
@@ -1478,10 +1478,10 @@ function Retry-FailedQueueEntry {
|
|||||||
[Parameter(Mandatory)]$Entry
|
[Parameter(Mandatory)]$Entry
|
||||||
)
|
)
|
||||||
|
|
||||||
$pendingPath = Get-PendingQueuePath -Config$Config
|
$pendingPath = Get-PendingQueuePath -Config $Config
|
||||||
New-Item -ItemType Directory -Path $pendingPath -Force | Out-Null
|
New-Item -ItemType Directory -Path $pendingPath -Force | Out-Null
|
||||||
|
|
||||||
$targetEml = Join-Path $pendingPath$Entry.FileName
|
$targetEml = Join-Path $pendingPath $Entry.FileName
|
||||||
$targetMeta = "$targetEml.json"
|
$targetMeta = "$targetEml.json"
|
||||||
|
|
||||||
if (Test-Path -LiteralPath $targetEml) {
|
if (Test-Path -LiteralPath $targetEml) {
|
||||||
@@ -1489,35 +1489,36 @@ function Retry-FailedQueueEntry {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($Entry.Meta) {
|
if ($Entry.Meta) {
|
||||||
$meta =$Entry.Meta
|
$meta = $Entry.Meta
|
||||||
|
|
||||||
if ($meta.PSObject.Properties.Name -contains "RetryCount") {
|
if ($meta.PSObject.Properties.Name -contains "RetryCount") {
|
||||||
$meta.RetryCount = 0
|
$meta.RetryCount = 0
|
||||||
} else {$meta | Add-Member -NotePropertyName RetryCount -NotePropertyValue 0
|
} else {
|
||||||
|
$meta | Add-Member -NotePropertyName RetryCount -NotePropertyValue 0
|
||||||
}
|
}
|
||||||
|
|
||||||
$now = [DateTime]::UtcNow.ToString("o")
|
$now = [DateTime]::UtcNow.ToString("o")
|
||||||
|
|
||||||
if ($meta.PSObject.Properties.Name -contains "NextAttemptUtc") {
|
if ($meta.PSObject.Properties.Name -contains "NextAttemptUtc") {
|
||||||
$meta.NextAttemptUtc =$now
|
$meta.NextAttemptUtc = $now
|
||||||
} else {
|
} else {
|
||||||
$meta | Add-Member -NotePropertyName NextAttemptUtc -NotePropertyValue$now
|
$meta | Add-Member -NotePropertyName NextAttemptUtc -NotePropertyValue $now
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($meta.PSObject.Properties.Name -contains "RequeuedUtc") {
|
if ($meta.PSObject.Properties.Name -contains "RequeuedUtc") {
|
||||||
$meta.RequeuedUtc =$now
|
$meta.RequeuedUtc = $now
|
||||||
} else {
|
} else {
|
||||||
$meta | Add-Member -NotePropertyName RequeuedUtc -NotePropertyValue$now
|
$meta | Add-Member -NotePropertyName RequeuedUtc -NotePropertyValue $now
|
||||||
}
|
}
|
||||||
|
|
||||||
$meta | ConvertTo-Json -Depth 10 | Set-Content -LiteralPath$Entry.MetaPath -Encoding UTF8
|
$meta | ConvertTo-Json -Depth 10 | Set-Content -LiteralPath $Entry.MetaPath -Encoding UTF8
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Test-Path -LiteralPath $Entry.MetaPath) {
|
if (Test-Path -LiteralPath $Entry.MetaPath) {
|
||||||
Move-Item -LiteralPath $Entry.MetaPath -Destination$targetMeta -Force
|
Move-Item -LiteralPath $Entry.MetaPath -Destination $targetMeta -Force
|
||||||
}
|
}
|
||||||
|
|
||||||
Move-Item -LiteralPath $Entry.Path -Destination$targetEml -Force
|
Move-Item -LiteralPath $Entry.Path -Destination $targetEml -Force
|
||||||
}
|
}
|
||||||
|
|
||||||
function Remove-FailedQueueEntry {
|
function Remove-FailedQueueEntry {
|
||||||
@@ -1528,7 +1529,7 @@ function Remove-FailedQueueEntry {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function Manage-FailedQueue {
|
function Manage-FailedQueue {
|
||||||
$config = Get-RelayConfig -TargetPath$InstallPath
|
$config = Get-RelayConfig -TargetPath $InstallPath
|
||||||
|
|
||||||
if (-not $config) {
|
if (-not $config) {
|
||||||
Write-Fail "config.json nicht gefunden."
|
Write-Fail "config.json nicht gefunden."
|
||||||
@@ -1539,7 +1540,7 @@ function Manage-FailedQueue {
|
|||||||
Clear-Host
|
Clear-Host
|
||||||
Write-Title "SMTPGraphRelay - Failed Queue"
|
Write-Title "SMTPGraphRelay - Failed Queue"
|
||||||
|
|
||||||
$entries = @(Get-FailedQueueEntries -Config$config)
|
$entries = @(Get-FailedQueueEntries -Config $config)
|
||||||
|
|
||||||
Write-Host "Failed-Mails: $($entries.Count)"
|
Write-Host "Failed-Mails: $($entries.Count)"
|
||||||
Write-Host ""
|
Write-Host ""
|
||||||
@@ -1572,8 +1573,8 @@ function Manage-FailedQueue {
|
|||||||
"2" {
|
"2" {
|
||||||
$id = Read-Host "Queue-ID"
|
$id = Read-Host "Queue-ID"
|
||||||
|
|
||||||
$entry =$entries |
|
$entry = $entries |
|
||||||
Where-Object { $_.QueueId -eq$id -or $_.FileName -eq$id -or $_.FileName -eq "$id.eml" } |
|
Where-Object { $_.QueueId -eq $id -or $_.FileName -eq $id -or $_.FileName -eq "$id.eml" } |
|
||||||
Select-Object -First 1
|
Select-Object -First 1
|
||||||
|
|
||||||
if (-not $entry) {
|
if (-not $entry) {
|
||||||
@@ -1601,15 +1602,15 @@ function Manage-FailedQueue {
|
|||||||
"3" {
|
"3" {
|
||||||
$id = Read-Host "Queue-ID"
|
$id = Read-Host "Queue-ID"
|
||||||
|
|
||||||
$entry =$entries |
|
$entry = $entries |
|
||||||
Where-Object { $_.QueueId -eq$id -or $_.FileName -eq$id -or $_.FileName -eq "$id.eml" } |
|
Where-Object { $_.QueueId -eq $id -or $_.FileName -eq $id -or $_.FileName -eq "$id.eml" } |
|
||||||
Select-Object -First 1
|
Select-Object -First 1
|
||||||
|
|
||||||
if (-not $entry) {
|
if (-not $entry) {
|
||||||
Write-Fail "Queue-ID '$id' nicht gefunden."
|
Write-Fail "Queue-ID '$id' nicht gefunden."
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Retry-FailedQueueEntry -Config $config -Entry$entry
|
Retry-FailedQueueEntry -Config $config -Entry $entry
|
||||||
Write-Ok "[$($entry.QueueId)] zurück nach pending verschoben."
|
Write-Ok "[$($entry.QueueId)] zurück nach pending verschoben."
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1621,11 +1622,13 @@ function Manage-FailedQueue {
|
|||||||
Write-Ok "Failed Queue ist leer."
|
Write-Ok "Failed Queue ist leer."
|
||||||
}
|
}
|
||||||
elseif (Confirm-Yes "Alle $($entries.Count) Failed-Mails erneut zustellen?") {
|
elseif (Confirm-Yes "Alle $($entries.Count) Failed-Mails erneut zustellen?") {
|
||||||
$ok = 0$failed = 0
|
$ok = 0
|
||||||
|
$failed = 0
|
||||||
|
|
||||||
foreach ($entry in$entries) {
|
foreach ($entry in $entries) {
|
||||||
try {
|
try {
|
||||||
Retry-FailedQueueEntry -Config $config -Entry $entry$ok++
|
Retry-FailedQueueEntry -Config $config -Entry $entry
|
||||||
|
$ok++
|
||||||
}
|
}
|
||||||
catch {
|
catch {
|
||||||
$failed++
|
$failed++
|
||||||
@@ -1645,8 +1648,8 @@ function Manage-FailedQueue {
|
|||||||
"5" {
|
"5" {
|
||||||
$id = Read-Host "Queue-ID"
|
$id = Read-Host "Queue-ID"
|
||||||
|
|
||||||
$entry =$entries |
|
$entry = $entries |
|
||||||
Where-Object { $_.QueueId -eq$id -or $_.FileName -eq$id -or $_.FileName -eq "$id.eml" } |
|
Where-Object { $_.QueueId -eq $id -or $_.FileName -eq $id -or $_.FileName -eq "$id.eml" } |
|
||||||
Select-Object -First 1
|
Select-Object -First 1
|
||||||
|
|
||||||
if (-not $entry) {
|
if (-not $entry) {
|
||||||
@@ -1668,9 +1671,10 @@ function Manage-FailedQueue {
|
|||||||
if (Confirm-Yes "Endgültiges Löschen nochmals bestätigen?") {
|
if (Confirm-Yes "Endgültiges Löschen nochmals bestätigen?") {
|
||||||
$ok = 0
|
$ok = 0
|
||||||
|
|
||||||
foreach ($entry in$entries) {
|
foreach ($entry in $entries) {
|
||||||
try {
|
try {
|
||||||
Remove-FailedQueueEntry -Entry $entry$ok++
|
Remove-FailedQueueEntry -Entry $entry
|
||||||
|
$ok++
|
||||||
}
|
}
|
||||||
catch {
|
catch {
|
||||||
Write-Warn "[$($entry.QueueId)] konnte nicht gelöscht werden."
|
Write-Warn "[$($entry.QueueId)] konnte nicht gelöscht werden."
|
||||||
@@ -1694,19 +1698,19 @@ function Manage-FailedQueue {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$config = Get-RelayConfig -TargetPath$InstallPath
|
$config = Get-RelayConfig -TargetPath $InstallPath
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function Manage-SmtpAuth {
|
function Manage-SmtpAuth {
|
||||||
$config = Get-RelayConfig -TargetPath$InstallPath
|
$config = Get-RelayConfig -TargetPath $InstallPath
|
||||||
|
|
||||||
if (-not $config) {
|
if (-not $config) {
|
||||||
Write-Fail "config.json nicht gefunden."
|
Write-Fail "config.json nicht gefunden."
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
$config = Ensure-SmtpAuthConfig -Config$config
|
$config = Ensure-SmtpAuthConfig -Config $config
|
||||||
|
|
||||||
while ($true) {
|
while ($true) {
|
||||||
Clear-Host
|
Clear-Host
|
||||||
@@ -1767,8 +1771,8 @@ function Manage-SmtpAuth {
|
|||||||
$p1 = Read-Host "Passwort" -AsSecureString
|
$p1 = Read-Host "Passwort" -AsSecureString
|
||||||
$p2 = Read-Host "Passwort wiederholen" -AsSecureString
|
$p2 = Read-Host "Passwort wiederholen" -AsSecureString
|
||||||
|
|
||||||
$plain1 = ConvertTo-PlainText -SecureString$p1
|
$plain1 = ConvertTo-PlainText -SecureString $p1
|
||||||
$plain2 = ConvertTo-PlainText -SecureString$p2
|
$plain2 = ConvertTo-PlainText -SecureString $p2
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if ($plain1.Length -lt 8) {
|
if ($plain1.Length -lt 8) {
|
||||||
@@ -1936,4 +1940,209 @@ function Manage-SmtpAuth {
|
|||||||
|
|
||||||
# Config nach jeder Änderung neu laden, damit Serialisierung/Arrays exakt
|
# Config nach jeder Änderung neu laden, damit Serialisierung/Arrays exakt
|
||||||
# dem installierten Zustand entsprechen.
|
# dem installierten Zustand entsprechen.
|
||||||
$config = Get-Rel
|
$config = Get-RelayConfig -TargetPath$InstallPath
|
||||||
|
$config = Ensure-SmtpAuthConfig -Config$config
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function Invoke-FailureModeTests {
|
||||||
|
Write-Title "SMTPGraphRelay - Failure Mode QA"
|
||||||
|
|
||||||
|
$tester = Join-Path$InstallPath "Test-SMTPGraphRelay-FailureModes.ps1"
|
||||||
|
if (-not (Test-Path -LiteralPath $tester)) {
|
||||||
|
Write-Fail "Test-SMTPGraphRelay-FailureModes.ps1 ist nicht installiert."
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
& $tester -InstallPath$InstallPath
|
||||||
|
}
|
||||||
|
|
||||||
|
function Uninstall-Relay {
|
||||||
|
Write-Title "SMTPGraphRelay - Deinstallation"
|
||||||
|
|
||||||
|
$config = Get-RelayConfig -TargetPath$InstallPath
|
||||||
|
|
||||||
|
Write-Warn "Lokale Deinstallation entfernt Task, Firewallregel und auf Wunsch das lokale Zertifikat."
|
||||||
|
if (-not (Confirm-Yes "Lokale SMTPGraphRelay-Installation wirklich entfernen?")) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
Stop-RelayTask
|
||||||
|
Unregister-ScheduledTask -TaskName $TaskName -Confirm:$false -ErrorAction SilentlyContinue
|
||||||
|
Write-Ok "Scheduled Task entfernt."
|
||||||
|
|
||||||
|
Get-NetFirewallRule -ErrorAction SilentlyContinue |
|
||||||
|
Where-Object { $_.DisplayName -like "SMTPGraphRelay TCP *" } |
|
||||||
|
Remove-NetFirewallRule -ErrorAction SilentlyContinue
|
||||||
|
Write-Ok "SMTPGraphRelay Firewallregeln entfernt."
|
||||||
|
|
||||||
|
if ($config -and$config.Graph.CertificateThumbprint) {
|
||||||
|
if (Confirm-Yes "Lokales Relay-Zertifikat $($config.Graph.CertificateThumbprint) entfernen?") {
|
||||||
|
Remove-Item -LiteralPath "Cert:\LocalMachine\My\$($config.Graph.CertificateThumbprint)" -Force -ErrorAction SilentlyContinue
|
||||||
|
Write-Ok "Lokales Zertifikat entfernt."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($config -and (Confirm-Yes "Auch Entra-App entfernen?")) {
|
||||||
|
Ensure-Modules
|
||||||
|
|
||||||
|
Write-Warn "Cloud-Cleanup ist destruktiv und betrifft die konfigurierte ClientId:"
|
||||||
|
Write-Host " $($config.Graph.ClientId)" -ForegroundColor Yellow
|
||||||
|
|
||||||
|
if (Confirm-Yes "Cloud-Cleanup endgültig bestätigen?") {
|
||||||
|
Connect-RelayGraphAdmin -TenantId $config.Graph.TenantId
|
||||||
|
|
||||||
|
try {
|
||||||
|
$app = Get-MgApplication -Filter "appId eq '$($config.Graph.ClientId)'" -Property "id,appId,displayName" | Select-Object -First 1
|
||||||
|
$sp = Get-MgServicePrincipal -Filter "appId eq '$($config.Graph.ClientId)'" -Property "id,appId,displayName" | Select-Object -First 1
|
||||||
|
|
||||||
|
if ($sp) {
|
||||||
|
Remove-MgServicePrincipal -ServicePrincipalId $sp.Id -ErrorAction SilentlyContinue
|
||||||
|
Write-Ok "Entra Service Principal entfernt."
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($app) {
|
||||||
|
Remove-MgApplication -ApplicationId $app.Id -ErrorAction SilentlyContinue
|
||||||
|
Write-Ok "Entra App Registration entfernt."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
Disconnect-MgGraph -ErrorAction SilentlyContinue | Out-Null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Programmdateien. Wenn der Installer selbst aus dem Zielordner läuft, kann er
|
||||||
|
# sich nicht zuverlässig selbst löschen. Dann bleiben Setup + Ordner bis nach Ende stehen.
|
||||||
|
$currentInstaller = [IO.Path]::GetFullPath($PSCommandPath)
|
||||||
|
$targetFull = [IO.Path]::GetFullPath($InstallPath)
|
||||||
|
|
||||||
|
foreach ($item in Get-ChildItem -LiteralPath$InstallPath -Force -ErrorAction SilentlyContinue) {
|
||||||
|
try {
|
||||||
|
if ($item.FullName -eq$currentInstaller) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
Remove-Item -LiteralPath $item.FullName -Recurse -Force -ErrorAction Stop
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
Write-Warn "Konnte nicht entfernen: $($item.FullName)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Ok "Lokale Programmdateien entfernt."
|
||||||
|
if ($currentInstaller.StartsWith($targetFull, [StringComparison]::OrdinalIgnoreCase)) {
|
||||||
|
Write-Warn "Der aktuell laufende Installer bleibt übrig. Nach dem Beenden kann '$InstallPath' manuell gelöscht werden."
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Title "Deinstallation abgeschlossen"
|
||||||
|
}
|
||||||
|
|
||||||
|
function Show-Status {
|
||||||
|
Write-Title "SMTPGraphRelay - Status"
|
||||||
|
|
||||||
|
$configPath = Join-Path $InstallPath$ConfigFileName
|
||||||
|
Write-Host "Installationspfad: $InstallPath"
|
||||||
|
|
||||||
|
if (Test-Path -LiteralPath $configPath) {
|
||||||
|
Write-Ok "config.json vorhanden."
|
||||||
|
try {
|
||||||
|
$config = Get-RelayConfig -TargetPath$InstallPath
|
||||||
|
Write-Host " Sender: $($config.Graph.SenderMailbox) (ForceSender: $($config.Graph.ForceSender))"
|
||||||
|
Write-Host " SMTP: $($config.Smtp.ListenAddress):$($config.Smtp.Port)"
|
||||||
|
Write-Host " Client: $($config.Graph.ClientId)"
|
||||||
|
|
||||||
|
if ($config.Smtp.PSObject.Properties.Name -contains "RequireAuth") {
|
||||||
|
$authText = if ([bool]$config.Smtp.RequireAuth) { "erforderlich" } else { "optional / aus" }
|
||||||
|
$authUsers = if ($config.Smtp.PSObject.Properties.Name -contains "AuthUsers") { @($config.Smtp.AuthUsers).Count } else { 0 }
|
||||||
|
Write-Host " AUTH: $authText ($authUsers Benutzer)"
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$failedCount = @(Get-FailedQueueEntries -Config$config).Count
|
||||||
|
Write-Host " Failed: $failedCount Mail(s)"
|
||||||
|
} catch {}
|
||||||
|
} catch {}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Write-Warn "Keine config.json vorhanden."
|
||||||
|
}
|
||||||
|
|
||||||
|
$task = Get-ScheduledTask -TaskName$TaskName -ErrorAction SilentlyContinue
|
||||||
|
if ($task) {
|
||||||
|
Write-Host "Task State: $($task.State)"
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Write-Warn "Scheduled Task nicht vorhanden."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function Show-Menu {
|
||||||
|
Clear-Host
|
||||||
|
Write-Title "SMTPGraphRelay - Bootstrap / Repair / Online Update"
|
||||||
|
Write-Host "Installationspfad: $InstallPath" -ForegroundColor DarkGray
|
||||||
|
|
||||||
|
$installedVersion = Get-InstalledVersion -TargetPath$InstallPath
|
||||||
|
|
||||||
|
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 aus Gitea"
|
||||||
|
Write-Host " [2] Installation aus Gitea reparieren"
|
||||||
|
Write-Host " [3] Nach Online-Updates suchen"
|
||||||
|
Write-Host " [4] Entra App & Berechtigungen prüfen"
|
||||||
|
Write-Host " [5] Zertifikat erneuern"
|
||||||
|
Write-Host " [6] Health Check ausführen"
|
||||||
|
Write-Host " [7] Deinstallieren"
|
||||||
|
Write-Host " [8] Status anzeigen"
|
||||||
|
Write-Host " [9] SMTP-AUTH verwalten"
|
||||||
|
Write-Host " [10] Failed Queue verwalten"
|
||||||
|
Write-Host " [11] Failure-Mode QA"
|
||||||
|
Write-Host " [0] Beenden"
|
||||||
|
Write-Host ""
|
||||||
|
}
|
||||||
|
|
||||||
|
Assert-WindowsPowerShell51
|
||||||
|
|
||||||
|
while ($true) {
|
||||||
|
Show-Menu
|
||||||
|
$choice = Read-Host "Auswahl"
|
||||||
|
|
||||||
|
try {
|
||||||
|
switch ($choice) {
|
||||||
|
"1" { Install-New }
|
||||||
|
"2" { Repair-Installation }
|
||||||
|
"3" { Update-Relay }
|
||||||
|
"4" { Verify-CloudPermissions }
|
||||||
|
"5" { Invoke-CertificateRenewal }
|
||||||
|
"6" { Invoke-HealthCheck }
|
||||||
|
"7" { Uninstall-Relay }
|
||||||
|
"8" { Show-Status }
|
||||||
|
"9" { Manage-SmtpAuth }
|
||||||
|
"10" { Manage-FailedQueue }
|
||||||
|
"11" { Invoke-FailureModeTests }
|
||||||
|
"0" { break }
|
||||||
|
default { Write-Warn "Ungültige Auswahl." }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
Write-Host ""
|
||||||
|
Write-Fail $_.Exception.Message
|
||||||
|
if ($_.ScriptStackTrace) {
|
||||||
|
Write-Host $_.ScriptStackTrace -ForegroundColor DarkYellow
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($choice -ne "0") {
|
||||||
|
Write-Host ""
|
||||||
|
Read-Host "Enter drücken, um zum Menü zurückzukehren"
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($choice -eq "0") {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in new issue
Block a user