<# .SYNOPSIS Ruft eine Webseite ab, extrahiert die Textausgabe und oeffnet damit eine neue Mail im Standard-Mailprogramm. .DESCRIPTION - Laedt die URL (PowerShell 5.1 / Windows 10 kompatibel, TLS 1.2 erzwungen). - text/plain wird direkt uebernommen, HTML wird in lesbaren Text umgewandelt. - Ist Outlook (klassisch) der Standard-Mailclient, wird die Mail per COM erstellt (keine Laengenbegrenzung). Andernfalls per mailto:, bei ueberlaenge gekuerzt; der vollstaendige Text liegt dann in der Zwischenablage. .EXAMPLE .\Send-WebTextToMail.ps1 -Url "https://check.example.de/report/abc123.txt" .EXAMPLE .\Send-WebTextToMail.ps1 -Url "https://intern.local/status" -SkipCertificateCheck -ForceMailto #> [CmdletBinding()] param( [Parameter(Mandatory)] [string]$Url = 'https://internetdb.shodan.io', [string]$To = 'ticket@hsp-edv.de', [string]$Subject = 'php2shell: Offene Ports auf primaerem WAN-Interface', # Maximale Gesamtlaenge der mailto-URL (Outlook/Windows-Shell ca. 2048) [int]$MaxMailtoLength = 1800, # Selbstsignierte Zertifikate akzeptieren (nur fuer interne Ziele!) [switch]$SkipCertificateCheck, # Immer mailto verwenden, auch wenn Outlook Standard ist [switch]$ForceMailto ) $ErrorActionPreference = 'Stop' # --- TLS / Zertifikate (PS 5.1) ------------------------------------------------- [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 -bor [Net.SecurityProtocolType]::Tls11 if ($SkipCertificateCheck) { if ($PSVersionTable.PSVersion.Major -ge 6) { $PSDefaultParameterValues['Invoke-WebRequest:SkipCertificateCheck'] = $true } else { [Net.ServicePointManager]::ServerCertificateValidationCallback = { $true } } } # --- Abruf ----------------------------------------------------------------------- try { $resp = Invoke-WebRequest -Uri $Url -UseBasicParsing -TimeoutSec 30 } catch { Write-Error "Abruf von $Url fehlgeschlagen: $($_.Exception.Message)" exit 1 } # Inhalt explizit als UTF-8 dekodieren (PS 5.1 raet sonst ISO-8859-1, wenn charset fehlt) $charset = 'utf-8' $ct = [string]$resp.Headers['Content-Type'] if ($ct -match 'charset=([\w\-]+)') { $charset = $Matches[1] } $bytes = $resp.RawContentStream.ToArray() $raw = [Text.Encoding]::GetEncoding($charset).GetString($bytes) # --- HTML -> Text ---------------------------------------------------------------- function ConvertFrom-HtmlToText([string]$html) { $t = $html $t = [regex]::Replace($t, '(?is)<(script|style|noscript|head)[^>]*>.*?', '') $t = [regex]::Replace($t, '(?i)', "`n") $t = [regex]::Replace($t, '(?i)', "`n") $t = [regex]::Replace($t, '(?i)]*>', '- ') $t = [regex]::Replace($t, '(?i)', "`t") $t = [regex]::Replace($t, '(?s)<[^>]+>', '') $t = [Net.WebUtility]::HtmlDecode($t) $lines = $t -split "`r?`n" | ForEach-Object { ($_ -replace '[ \t]+', ' ').Trim() } # mehrfache Leerzeilen zusammenfassen ($lines -join "`n") -replace "(`n){3,}", "`n`n" } $text = if ($ct -match 'text/plain') { $raw } else { ConvertFrom-HtmlToText $raw } $text = $text.Trim() if (-not $text) { Write-Error "Die Seite lieferte keinen Text."; exit 1 } $footer = @' Hallo HSP-Team, bitte melden Sie sich zu diesem Thema bei: Ansprechpartner zu diesem Thema (Name, E-Mail, Telefon) Wir vermuten, dass folgende unserer Anwendungen betroffen sein koennten: (sofern bekannt) Bitte gehen Sie wie folgt vor: (Dienst schliessen bzw. offline nehmen/Dienst vorerst online lassen, aber das Risiko bewerten /Rueckruf zur Abstimmung erwuenscht) '@ $body = "Quelle: $Url`r`nAbgerufen: $(Get-Date -Format 'dd.MM.yyyy HH:mm:ss') auf $env:COMPUTERNAME`r`n`r`n" + ($text -replace "`r?`n", "`r`n") + "`r`n`r`n----------------------------------------`r`n`r`n" + ($footer -replace "`r?`n", "`r`n") # --- Standard-Mailclient ermitteln ------------------------------------------------ $progId = (Get-ItemProperty -Path 'HKCU:\Software\Microsoft\Windows\Shell\Associations\UrlAssociations\mailto\UserChoice' -ErrorAction SilentlyContinue).ProgId Write-Verbose "mailto-Handler: $progId" # --- Variante 1: Outlook klassisch per COM ---------------------------------------- if (-not $ForceMailto -and $progId -match '^Outlook\.') { try { $ol = New-Object -ComObject Outlook.Application $mail = $ol.CreateItem(0) # olMailItem $mail.To = $To $mail.Subject = $Subject $mail.Body = $body $mail.Display() Write-Host "Neue Outlook-Mail geoeffnet ($($body.Length) Zeichen)." exit 0 } catch { Write-Warning "Outlook-COM nicht verfuegbar ($($_.Exception.Message)) - weiche auf mailto aus." } } # --- Variante 2: mailto ----------------------------------------------------------- function New-MailtoUri([string]$b) { 'mailto:{0}?subject={1}&body={2}' -f $To, [uri]::EscapeDataString($Subject), [uri]::EscapeDataString($b) } $uri = New-MailtoUri $body if ($uri.Length -gt $MaxMailtoLength) { Set-Clipboard -Value $body $note = "`r`n`r`n[... gekuerzt - vollstaendiger Text liegt in der Zwischenablage, bitte mit Strg+V hier einfuegen]" $cut = $body.Length do { $cut = [int]($cut * 0.9) $uri = New-MailtoUri ($body.Substring(0, $cut) + $note) } while ($uri.Length -gt $MaxMailtoLength -and $cut -gt 50) Write-Warning "Text zu lang fuer mailto - gekuerzt auf $cut Zeichen, Volltext in Zwischenablage." } Start-Process $uri Write-Host "Neue Mail im Standard-Mailprogramm geoeffnet."