Exchange 2007: PowerShell-Script für beliebige Weiterleitungen

Inhaltsverzeichnis

 

1. Vorwort Inhalt

Hin und wieder kommt es vor, dass ein Abieter von eMail-Diensten sich mit der Problemstellung konfrontiert sieht, eMails für Benutzer an ein lokales Postfach und eine oder mehrere (unternehmens-)externe Mailboxen weiterzuleiten, insbesondere, wenn die Mail-Serverlandschaft nicht homogen ist.

Unter Unix-Mailern bereitet eine solche Konfiguration keine Schwierigkeit, die einfachste Variante ist eine „.forward“-Datei im Homedirectory des Anwenders. Unter Exchange allerdings besteht für den Benutzer selbst nur die Möglichkeit, eine Weiterleitungsregel einzurichten, wobei die Lösung besonders bei vielen (heißt 20 000 und mehr) stark frequentierten Mailboxen sehr auf die Serverlast geht.

Zugleich ist es recht schwer für einen Helpdesk, unbedarften Anwendern den Unterschied zwischen „Umleitung“ und „Weiterleitung“ zu erklären und Hilfestellungen für die unterschiedlichen eMail-Clients bereitzuhalten.

2. Szenario Inhalt

SzenarioEs sei das links abgebildete Szenario gegeben. Zum einen habe man einen großen Unix-Mailserver, der für „Standard“-Maildienste (POP, IMAP, SMTP) bereitsteht. Benutzer, die Groupware-Funktionen benötigen, werden von einem symmetrisch dazu betriebenen Exchange 2007-System bedient; es soll aber möglich sein, auf beiden Mailservern eine Mailbox zu besitzen und eine oder mehrere weitere externe Postfächer.

Beide Unternehmens-Server werden aus der gleichen Datenquelle mit Benutzerdaten (Namen, eMail-Adressen usw.) provisioniert.

Nun tut sich im Falle von Exchange ein Problem auf. Sofern der Benutzer im Active-Directory eine Mailbox besitzt, wird Exchange interne (d.h. von anderen Exchange-Benutzern versandte) eMails immer in diese Mailbox zustellen, auch wenn der Benutzer eigentlich eine andere Adresse benutzt.

Zwar könnte er eine Weiterleitung über MAPI-Regeln einrichten, hätte dann aber das Problem, dass die „FROM“- und „TO“-Headerzeilen nicht mehr denen der ursprünglichen Mail entsprechen.

3. Lösung – Theorie Inhalt

Das Problem betraf einen großen Rechenzentrumsbetreiber in Garching, für den ich die nachfolgende Lösung entwickelt habe. Erschwerend kam noch hinzu, dass für die Konfiguration des Mailsystems eine externe Oberfläche und nicht die nativen (OWA, Outlook) zur Anwendung kommt.

Exchange 2007 bietet die Möglichkeit, eMails für einen Benutzer an ein anderes, eMail-fähiges AD-Objekt (Kontakt oder Verteiler-Gruppe) weiterzuleiten und dabei wahlweise eine Kopie in die lokale Mailbox zuzustellen. Dies ist über die Oberfläche (Exchange Management Shell) und über PowerShell-Scripte konfigurierbar.

Der Unterschied zur MAPI-Weiterleitung ist einfach, dass hier die Headerzeilen erhalten bleiben, da Exchange dann mittels Envelope-Header weiterleitet; der Empfänger sieht nun auch in einer völlig fremden Mailbox noch den ursprünglichen Absender anstatt seine eigene Exchange-Absenderkennung.

Die Lösung besteht nun darin, einfach einen Kontakt für die gewünschte Adresse anzulegen (der Name ist egal, der wird nicht angezeigt im Zielmailsystem) und dem Benutzer diesen Kontakt als Forward-Ziel zu konfigurieren. Nachdem man noch festlegen kann, in welcher OU der Kontakt erstellt wird, behindern diese neuen Objekte auch keine bestehenden Funktionen und tauchen auch nicht in den Adresslisten auf.

Eine Schwierigkeit ergibt sich noch, wenn der Benutzer an mehr als eine Adresse weiterleiten möchte oder wenn ein Kontakt von mehr als einem Benutzer als Weiterleitungsziel verwendet wird. In diesem Falle ist dann zunächst eine Verteilergruppe zu erstellen und diese als Forward-Ziel festzulegen. Danach müssen die einzelnen Kontakte erstellt und der Gruppe hinzugefügt werden.

4. Lösung – Praxis Inhalt

Das folgende Script erledigt die Aufgaben; als Parameter sind die Mailboxkennung (z.B. Loginname) und die Ziel-Adressen zu übergeben. Optional kann mit dem dritten Parameter die lokale Kopie aktiviert oder deaktiviert werden. Sofern keine Adressen übergeben wurden, werden die Forwards gelöscht und es findet nur noch eine Zustellung an die lokale Mailbox statt. Anmerkung: Nach dem Löschen von Forwards können unter Umständen Kontakte „verwaist“ zurückbleiben. Wenn diese Objekte stören, könnte man sie über einen Batch-Job noch entfernen.

PowerShell-Skript zum Setzen und Löschen von Forwards in Exchange 2007
Param(
  [string]  $MBKennung  = "",            # Kennung der zu suchenden Mailbox
  [string]  $Addresses  = "",            # Kommaseparierte Liste aus externen Adressen und/oder Mailboxkennungen
  [boolean] $CopyToLocalMailbox = $false # Mails auch in Exchange-Mailbox liefern?
)

# This function validates the scripts parameters
function ValidateParams {
  $validInputs = $true
  $errorString = ""
  if ($MBKennung -eq "") {
    $validInputs = $false
    $errorString += "Missing parameter: The MBKennung parameter is required. Please pass in a valid LRZ-Kennung (gu55nop)."
  }
  if (!$validInputs) { write-error "$errorString" }
  return $validInputs
}

# Fehlerausgabe unterdrücken
$ErrorActionPreference="SilentlyContinue"
write-output "Checking Parameters..."
$ifValidParams = ValidateParams;
if (!$ifValidParams) { exit; }
write-output "...done"
$MBKennung = $MBKennung.ToString().ToLower()

$mailbox = get-mailbox -identity "$MBKennung"
if (!$mailbox) {
  $ErrorActionPreference="Continue"
  write-error "Fehler: Mailbox mit Kennung '$MBKennung' konnte nicht gefunden werden."
  exit;
}

$mailboxName = $mailbox.Name
write-output "Ok, Identität gefunden. Name ist '$mailboxName'." ""

if ($Addresses -ne "" -and $Addresses -ne $null) {
  $AddressesArray = $Addresses.Split(",")
  $l = $AddressesArray.length
  write-output "Es wurde(n) $l Adresse(n) übergeben ==> Forward(s) anlegen." ""

  # Ok, Forward-Gruppe anlegen
  # Alias wird "$MBKennung-forwardgroup"
  $gruppenAlias = "$MBKennung-forwardgroup"
  $gruppe  = get-distributiongroup -identity "$gruppenAlias" -RecipientTypeDetails MailUniversalDistributionGroup
  $gruppe2 = get-distributiongroup -identity "$gruppenAlias"
  if (!$gruppe2) {
    write-output "Gruppe mit Alias '$gruppenAlias' nicht gefunden."
    new-distributiongroup -Name "Forwardgruppe $MBKennung" -SamAccountName "$gruppenAlias" -Type Distribution -Alias "$gruppenAlias"
    $gruppe = get-distributiongroup -identity "$gruppenAlias"
    write-output "Gruppe mit Alias '$gruppenAlias' wurde angelegt." ""
  } elseif(!$gruppe -and $gruppe2) {
    # Fehlerausgabe einschalten
    $ErrorActionPreference="Continue"
    write-error "Gruppe mit Alias '$gruppenAlias' ist vorhanden, hat aber den falschen Typ. EXIT."
    exit;
  } else {
    # Gruppe löschen und neu anlegen (="leeren")
    Remove-DistributionGroup -identity "$gruppenAlias" -confirm:$false
    new-distributiongroup -Name "Forwardgruppe $MBKennung" -SamAccountName "$gruppenAlias" -Type Distribution -Alias "$gruppenAlias"
    $gruppe = get-distributiongroup -identity "$gruppenAlias"
    write-output "Gruppe mit Alias '$gruppenAlias' ist vorhanden. Wird verwendet." ""
  }

  # Jetzt die Gruppe als Forward in der Mailbox eintragen
  $mboxAlias   = $mailbox.alias
  $mboxForward = $gruppe.alias
  set-mailbox -identity "$mboxAlias" -ForwardingAddress "$mboxForward" -DeliverToMailboxAndForward $CopyToLocalMailbox

  # Jetzt schauen, ob jeder der Kontakte entweder als
  # Mailbox oder als MailContact existiert, und falls nein,
  # den Kontakt als MailContact anlegen.
  foreach ($address in $AddressesArray) {
    $address = $address.ToString().ToLower().Trim()
    write-output "Suche Kontakt oder Mailbox mit Adresse '$address'..."
    $mObjekt = get-mailbox -identity "$address"
    if (!$mObjekt) {
      write-output "  Mailbox mit Adresse '$address' nicht gefunden."
      $mObjekt = get-mailcontact -identity "$address"
      if (!$mObjekt) { write-output "  Kontakt mit Adresse '$address' nicht gefunden." }
    }

    # Ok, Kontakt neu anlegen...
    # Daten sind relativ egal, der ursprüngliche
    # "TO"-Header bleibt erhalten.
    if (!$mObjekt) {
      $aliasAddress=$address.replace("@", "{a}")
      new-mailcontact -Name "Forward '$address'" -Alias "Forward_$aliasAddress" -ExternalEmailAddress "$address" -confirm:$false
      write-output "  Neuer Mailkontakt mit SMTP-Adresse $address angelegt."
    }

    # und zur Gruppe hinzufügen
    Add-DistributionGroupMember -identity "$mboxForward" -member "$address" -confirm:$false
    write-output "  Mailkontakt mit SMTP-Adresse $address zu Gruppe $mboxForward hinzugefügt."
  }
} else {
  write-output "Es wurden keine Adressen übergeben ==> Forward(s) löschen." ""
  # Gut, Forwardgruppe aus dem AD löschen,
  # sie wird bei der Mailbox dann automatisch
  # aus "ForwardingAddress" entfernt.
  $gruppenAlias = "$MBKennung-forwardgroup"
  Remove-DistributionGroup -identity "$gruppenAlias" -confirm:$false
  write-output "Ok, Gruppe wurde aus Mailbox entfernt und gelöscht."
}
MBKennung

Bislang keine Kommentare vorhanden.

Einen Kommentar hinterlassen