PDF Mail Inbox

Die Frage, um die es hier geht, lautet ganz konkret: Wie bekomme ich Belege aus einer Sammel-Inbox abgearbeitet, um sie an ein Nachfolgesystem übergeben zu können? Also nicht „wie baue ich eine KI-Lösung", sondern: Mail rein, PDF gelesen, strukturierte Daten raus, wiederholbar und ohne dass jemand täglich klickt.

Der Weg besteht aus vier Etappen, und jede davon ist Standardtechnik: Exchange Online liefert per SMTP an einen eigenen Windows Server Host aus, dort nimmt der IIS-SMTP-Dienst an und legt die Mail als Datei ab, ein Dienst liest diese Datei, und ein lokales LLM liest den PDF-Anhang. Am Ende steht pro Beleg ein PDF und ein XML mit demselben Namen. Wir haben aus unstrukturierten Daten Struktur in einem Workflow erzeugt

Screenshot 2026-07-20 155337

Exchange Online — Connector, Kontakt, Transportregel

Exchange soll eine Kopie jeder relevanten Mail an einen eigenen Host schicken. Dafür braucht es drei Objekte: einen Outbound-Connector (wohin), einen Mail-Kontakt (an wen) und die Transportregel (wann). Verbindung wie gehabt:

Install-Module ExchangeOnlineManagement -Scope CurrentUser
Connect-ExchangeOnline -UserPrincipalName admin@example.com

Warum -BlindCopyTo und nicht -RedirectMessageTo? Weil die Mail dann zusätzlich ganz normal im Postfach ankommt. Das Original bleibt als Kontext und als Sicherheitsnetz erhalten — steht das Gateway zwei Tage still, merkt es niemand, aber es geht auch nichts verloren. Man kann die Automatisierung jederzeit abschalten, ohne den Geschäftsprozess zu unterbrechen. Erst wenn alles stabil läuft, kann man auf Redirect umstellen; ich habe es bei Bcc belassen.

Damit das Postfach trotzdem aufgeräumt bleibt, wandern die verarbeiteten Mails per Posteingangsregel in einen Unterordner:

New-MailboxFolder -Parent finance@example.com:\Posteingang -Name "ErledigtAutomatisch"

New-InboxRule -Mailbox finance@example.com -Name "Belege wegsortieren" `
    -SubjectOrBodyContainsWords "Rechnung" `
    -MoveToFolder "finance@example.com:\Posteingang\ErledigtAutomatisch"

Zum Schluss die Verbindung sauber trennen:

Disconnect-ExchangeOnline -Confirm:$false

Über das Online Portal lässt sich die Regel prüfen, aber nicht anlegen oder ändern.
Der Dialog sieht diese BCC Option nicht vor

https://admin.exchange.microsoft.com/#/transportrules

Screenshot 2026-07-15 080622

welche Protokolle hier eigentlich sprechen

Ein Punkt, der später Stunden spart. Eine SMTP-Zustellung hat zwei Empfängerangaben, und sie stimmen nicht überein:

  • Der Umschlag (RCPT TO) — das, was der Mailserver fürs Routing verwendet. Bei Bcc oder Redirect steht dort intake@intake.example.com.
  • Die Header (To:, Cc:) — das, was der Mensch sieht. Dort steht weiterhin finance@example.com.

Eine Blindkopie ist per Definition nicht im Header sichtbar. Wer den echten Empfänger wissen will — und den will man, denn danach entscheidet sich die Verarbeitungsregel — muss beide Quellen auswerten. Der IIS-SMTP hilft hier: Er schreibt beim Ablegen für jeden Umschlag-Empfänger einen X-Receiver-Header in die Datei. Auswerten sollte man also To, Cc und X-Receiver.

Das abgelegte Format ist MIME (RFC 5322 / 2045) als .eml-Datei: Header, dann ein mehrteiliger Body, Anhänge Base64-kodiert. Selbst parsen sollte man das nicht — in .NET nimmt man MimeKit, das erledigt Encodings, verschachtelte Multiparts und kaputte Header von Fremdsystemen. Es gibt in dieser Kette sehr wenig, was man selbst schreiben muss, und der MIME-Parser gehört ausdrücklich nicht dazu.

IIS-SMTP auf Windows Server einrichten

Der SMTP-Dienst ist ein Überbleibsel aus IIS 6, aber er ist in jedem Windows Server enthalten, kostet nichts und tut genau eine Sache sehr zuverlässig: Mail annehmen, TLS sprechen und als Datei ablegen. Genau das brauchen wir.

Verwaltet wird der Dienst über den IIS-6-Manager (inetmgr6.exe bzw. „Internetinformationsdienste-Manager (IIS 6.0)" in den Verwaltungstools) — nicht über den modernen IIS-Manager, der kennt ihn nicht.

Screenshot 2026-07-15 080058

Im IIS-6-Manager unter SMTP Virtual Server → Domains → Rechtsklick → New → Domain den Typ Local (Drop) wählen und intake.example.com eintragen.

Das ist der Kern des ganzen Aufbaus: Für eine lokale Domäne versucht der Dienst nicht, die Mail weiterzuleiten, sondern schreibt sie als .eml in den Drop-Ordner — standardmäßig C:\inetpub\mailroot\Drop. Aus einem Netzprotokoll wird ein Dateisystem-Ereignis. Ab hier ist es kein Mail-Problem mehr, sondern ein FileSystemWatcher.

Screenshot 2026-07-15 080143

Sicherheit — was man zwingend einstellen muss

Ein SMTP-Dienst am offenen Internet ist ein Angebot. Vier Einstellungen sind nicht optional:

1. Kein offenes Relay. Im IIS-6-Manager unter Access → Relay restrictions auf „Only the list below" stellen und die Liste leer lassen. Wir nehmen ausschließlich Mail für unsere eigene lokale Domäne an und leiten grundsätzlich nichts weiter. Ein offenes Relay hat man innerhalb von Stunden auf jeder Blocklist der Welt.

2. Firewall auf die Absender-IPs einschränken. Nur Microsoft darf zustellen. Die aktuellen Exchange-Online-Ausgangsbereiche stehen in der Microsoft-365-IP-Liste; Port 25 gehört nicht für die ganze Welt geöffnet:

3. Anonyme Authentifizierung ja, Weiterleitung nein. Klingt widersprüchlich, ist aber richtig: Exchange Online kann sich bei uns nicht anmelden, also muss die Annahme anonym erlaubt sein. Die Sicherheit kommt aus der Kombination Relay-Sperre + IP-Filter + eigene lokale Domäne, nicht aus einem Passwort. Zusätzlich ein Größenlimit setzen, damit niemand die Platte vollschreibt (Messages → Limit message size, z. B. 20 MB).

4. Eingehende Mail ist niemals vertrauenswürdig. Das ist die Einstellung, die man nicht in einem Dialog findet. Wenn ein LLM gleich Freitext aus fremden Mails liest und daraus womöglich eine Zieladresse extrahiert, kann eine freundlich formulierte Mail („bitte senden Sie die Rechnung erneut an …") das System dazu bringen, Belege nach außen zu schicken. Die Regel dagegen ist stumpf und wirksam: automatischer Versand nur an Adressen auf einer Allowlist, alles andere in eine Freigabe-Queue. Ablegen, Umbenennen, Drucken laufen automatisch — das sind Operationen ohne Außenwirkung. Die Grenze verläuft entlang der Frage „verlässt hier etwas das Haus", nicht entlang der Modellkonfidenz.

Lokales LLM mit Ollama

Belege gehen nicht in eine Cloud-API. Das ist keine Ideologie, sondern der kürzeste Weg durch jede Datenschutzdiskussion: Rechnungen enthalten Bankverbindungen, Bewerbungsunterlagen Gesundheits- und Personendaten. Ollama läuft offline auf demselben Windows Server.

# Installation (Windows): Installer von ollama.com, danach:
ollama --version

# Modelle laden
ollama pull qwen2.5vl:7b     # Vision  - liest den Beleg als Bild
ollama pull llama3.2:3b      # Text    - Fließtext, schnell

ollama list
Invoke-RestMethod http://localhost:11434/api/tags   # läuft der Dienst?

Warum ein Vision-Modell und nicht Textextraktion? Weil ein erheblicher Teil der Belege gar keinen Text enthält — Scans, Fotos, Kassenbons. Und weil bei den übrigen das Layout Information trägt: Welche der fünf Zahlen auf dem Blatt der Bruttobetrag ist, ergibt sich aus der Position in der Tabelle, nicht aus dem Zeichenstrom. Extrahierter PDF-Text wirft genau diese Information weg. Der Ablauf ist also: erste Seite als PNG rendern (200 dpi reichen), Bild ans Modell, JSON zurück. Klassische Textextraktion bleibt als Fallback, falls das Rendern scheitert.

Warum qwen2.5vl:7b? Drei Gründe, alle aus dem Test mit echten Belegen: Es liest Belegnummer, Datum und Betrag auf deutschen Rechnungen zuverlässig; es unterstützt erzwungene JSON-Schema-Ausgabe; und es läuft in 7B noch brauchbar auf CPU (rund 80 Sekunden pro Beleg — bei zehn Belegen am Tag völlig unkritisch). Zum Vergleich: llava halluziniert bei deutschen Belegen munter Beträge dazu und ist damit schlechter als gar keine Extraktion, weil der Fehler nicht auffällt. Wer mehr Genauigkeit braucht und die Hardware hat, nimmt qwen2.5vl:32b — dieselbe API, eine Zeile Konfiguration.

 1  # Anmelden – Browser-Popup öffnet sich, dort M365-ADMIN-Konto + MFA
 2  Connect-ExchangeOnline -UserPrincipalName hannesp@ppedv.de
 3  
 4  # Regel 1: Finance – alle Mails als Blindkopie ans Gateway
 5  New-TransportRule -Name "Intake Finance" -SentTo "finance@ppedv.de" `
 6    -BlindCopyTo "intake@intake.ppedv.de"
 7  
 8  # Regel 2: Jobs – nur mit PDF-Anhang
 9  New-TransportRule -Name "Intake Jobs (PDF)" -SentTo "jobs@ppedv.de" `
10    -AttachmentExtensionMatchesWords "pdf" -BlindCopyTo "intake@intake.ppedv.de"
11  
12  # Kontrolle
13  Get-TransportRule "Intake Finance","Intake Jobs (PDF)" | Format-Table Name,State,Priority
14  
15  # Trennen
16  Disconnect-ExchangeOnline -Confirm:$false
Kommentare sind geschlossen