Warum das Blockieren bestimmter TLDs die Sicherheit deines Postfachs massiv erhöht

Das gezielte Blockieren ausgewählter Top-Level-Domains (TLDs) ist eine der effektivsten Maßnahmen, um Phishing‑ und Spam‑Wellen frühzeitig auszubremsen.

Viele missbräuchlich genutzte Domains werden in Ländern registriert, in denen anonyme, günstige und schnell verfügbare Registrierungen möglich sind. Mit einer Mailflow‑Regel, die problematische TLDs am „From“-Header abfängt, reduzierst du sofort den Rauschteppich im Posteingang, entlastest Schutzmechanismen wie Safe Links und verringerst den Druck auf Benutzer, ständig zwischen legitimen und betrügerischen Mails unterscheiden zu müssen.

Eine kurze Audit‑Phase, plus gepflegte Allowlist, sorgt dafür, dass legitime Partner nicht fälschlich blockiert werden – bei gleichzeitig deutlich spürbarem Sicherheitsgewinn.

Wie die Regel technisch funktioniert – kurz erklärt

Die TLD‑Block‑Regel greift direkt im Exchange Online Mailflow, also an einer Stelle, an der eingehende E‑Mails zum ersten Mal geprüft werden. Dabei wird ausschließlich externer Traffic betrachtet – interne Nachrichten bleiben außen vor. Kern der Logik ist der Blick in den sichtbaren „From“-Header der E-Mail: Dort prüft Exchange mithilfe von regulären Ausdrücken, ob die Absenderadresse mit einer bestimmten Top-Level-Domain endet, etwa .ru, .cn oder .xyz.

Treffen diese Muster zu, wird die Mail sofort abgelehnt, bevor sie irgendein Postfach erreicht oder andere Sicherheitsebenen belastet. Das verhindert effektiv, dass Phishing oder Spam überhaupt im Unternehmen ankommt. Für legitime Partner lassen sich gezielte Ausnahmen hinterlegen, sodass wichtige Kommunikation nicht blockiert wird.

Dank eines optionalen Audit-Modus kannst du die Regel zunächst beobachten, ohne aktiv Mails zu verwerfen. Sobald klar ist, dass keine falschen Treffer auftreten, wird die Regel scharf geschaltet – und sorgt ab diesem Moment für deutlich mehr Ruhe und Sicherheit im Posteingang.

Die TLD‑Block‑Regel wirkt völlig unabhängig von SPF, DKIM und DMARC und verwirft Mails, bevor Authentifizierungsmechanismen greifen – genau dadurch reduziert sie den Aufwand, den Angreifer technisch korrekt signierte, aber dennoch bösartige Mails verursachen würden.

$patterns = @('\.ru$', '\.cn$', '\.xyz$', '\.tr$')

New-TransportRule -Name "Blockiere TLDs" -Priority 0  -FromScope NotInOrganizatio -HeaderMatchesMessageHeader "From" -HeaderMatchesPatterns $patterns -RejectMessageEnhancedStatusCode "5.7.1"

Hinweis/Disclaimer: Es erfolgt keine Garantie oder Gewährleistung für Funktion, Vollständigkeit oder Eignung in anderen Umgebungen.

**Stand:** 15.02.2026

KeePass‑Plugins automatisch aktuell halten – mein Setup in Kürze

Problem:

KeePass 2.x bringt keinen Mechanismus mit, um Plugins automatisch zu aktualisieren. Selbst wichtige Erweiterungen wie KeePassRPC (für die Browser‑Integration via „Kee“) melden zwar neue Versionen, doch das Einspielen muss manuell erfolgen.

Randbedingungen / Besonderheiten:

  • KeePassRPC wird zuverlässig über GitHub Releases ausgeliefert (z. B. v2.0.2 vom 12. Juni 2024).
  • KeeAutoExec ist offiziell gelistet und lässt sich unter Windows bequem über das Chocolatey‑Paket keepass-plugin-keeautoexec pflegen (verifizierte Pakettests).
  • GlobalSearch erweitert die Suche auf alle geöffneten KeePass‑Datenbanken; der Code liegt auf GitHub. [Keepass Pl…Seach.page | Loop]

Lösung: Ein Updater‑Skript + geplanter Task (ohne XML)

Ich nutze ein PowerShell‑Skript, das zwei Update‑Wege kombiniert:

  1. GitHub‑Releases prüfen und .plgx automatisch laden/aktualisieren (z. B. für KeePassRPC).
  1. Chocolatey‑Upgrade für KeeAutoExec (choco upgrade keepass-plugin-keeautoexec -y).

Dazu kommen Robustheits‑Details:

  • Sicherer Dateitausch inkl. Backup, optionales Stoppen/Neustarten von KeePass
  • Log‑Rollover und klare Fehlerlogs
  • Sorgfältige Klammerung/Interpolation, um typische PowerShell‑Parserfehler zu vermeiden

Die Automatisierung übernimmt ein geplanter Task, den ich per PowerShell‑Cmdlets (nicht per XML) registriere – das ist schema‑sicher und läuft beim Anmelden sowie täglich zur Wunschzeit mit höchsten Privilegien.


Was wird aktualisiert?

  • KeePassRPC (GitHub) – benötigt für die Browser‑Erweiterung Kee.
  • KeeAutoExec (Chocolatey) – öffnet definierte KeePass‑Datenbanken automatisch.
  • GlobalSearch (GitHub) – Suche über alle geöffneten DBs. [Keepass Pl…Seach.page | Loop]

Ergebnis

  • Zero‑Touch Updates meiner wichtigsten KeePass‑Plugins
  • Keine XML‑Frickelei: nur PowerShell
  • Nachvollziehbare Logs + Backups für schnelle Rollbacks
  • Einheitliche Pflege auf mehreren Systemen

🔧 Hinweis zur Anpassung (Vorlage erweiterbar)

Die Vorlage ist bewusst modular: Du kannst weitere Plugins hinzufügen (z. B. aus der offiziellen [KeePass‑Pluginliste]), entweder als GitHub‑Eintrag (Repo + Asset‑Filter) oder als Chocolatey‑Paket. Ebenso lassen sich Zeitpläne, Pfade (portable vs. installiert) und Benachrichtigungen (z. B. E‑Mail/Toast) unkompliziert erweitern.

hier das Updater Script


<#
KeePass Plugin Updater (bereinigt & produktiv)
Marko Fieber – 2026
#>

# ================================
# === Benutzer-Konfiguration  ====
# ================================

$KeePassExePath = "C:\Program Files\KeePass Password Safe 2\KeePass.exe"
$PluginDir      = "C:\Program Files\KeePass Password Safe 2\Plugins"

$WorkDir = "$env:ProgramData\KeePassPluginUpdater"
$LogFile = Join-Path $WorkDir "update.log"

$StopKeePassDuringUpdate = $true
$UsePreReleases = $false
$EnvGitHubToken = $env:GITHUB_TOKEN

$Plugins = @(
    @{
        Name         = "KeePassRPC"
        Repo         = "kee-org/keepassrpc"
        AssetPattern = "KeePassRPC\.plgx$"
        TargetFile   = "KeePassRPC.plgx"
    },
    @{
        Name         = "GlobalSearch"
        Repo         = "Rookiestyle/GlobalSearch"
        AssetPattern = "\.plgx$"
        TargetFile   = "GlobalSearch.plgx"
    },
    @{
        Name         = "KeeAutoExec"
        ChocoPackage = "keepass-plugin-keeautoexec"
        TargetFile   = "KeeAutoExec.plgx"
    }
)

# ================================
# === Hilfsfunktionen ============
# ================================

function Write-Log {
    param([string]$Msg, [string]$Level = "INFO")
    $ts = (Get-Date).ToString("yyyy-MM-dd HH:mm:ss")
    $line = "[$ts] [$Level] $Msg"
    Write-Host $line
    Add-Content $LogFile -Value $line
}

function Ensure-Dirs {
    if (-not (Test-Path $WorkDir)) { New-Item -ItemType Directory -Path $WorkDir | Out-Null }
}

function Set-Tls12 {
    try {
        [Net.ServicePointManager]::SecurityProtocol =
            [Net.SecurityProtocolType]::Tls12 -bor
            [Net.SecurityProtocolType]::Tls11 -bor
            [Net.SecurityProtocolType]::Tls
    } catch {}
}

function Get-GitHubRelease {
    param([string]$Repo, [bool]$IncludePreRelease=$false)

    $headers = @{ "User-Agent" = "KeePassPluginUpdater" }
    if ($EnvGitHubToken) { $headers["Authorization"] = "Bearer $EnvGitHubToken" }

    $url = "https://api.github.com/repos/$Repo/releases"
    $resp = Invoke-RestMethod -Uri $url -Headers $headers -ErrorAction Stop

    if ($IncludePreRelease) { return ($resp | Select-Object -First 1) }
    return ($resp | Where-Object { -not $_.prerelease } | Select-Object -First 1)
}

function Stop-KeePass {
    if (-not $StopKeePassDuringUpdate) { return }
    $p = Get-Process KeePass -ErrorAction SilentlyContinue
    if ($p) {
        Write-Log "Beende KeePass..."
        $p | Stop-Process -Force
        Start-Sleep -Seconds 2
    }
}

function Start-KeePass {
    if ($StopKeePassDuringUpdate -and (Test-Path $KeePassExePath)) {
        Write-Log "Starte KeePass neu..."
        Start-Process $KeePassExePath | Out-Null
    }
}

function Backup-File {
    param([string]$FilePath)
    if (Test-Path $FilePath) {
        $backupDir = Join-Path $WorkDir "backups"
        if (-not (Test-Path $backupDir)) { New-Item -ItemType Directory -Path $backupDir | Out-Null }
        $stamp = (Get-Date).ToString("yyyyMMdd-HHmmss")
        $dest  = Join-Path $backupDir ("$(Split-Path $FilePath -Leaf).$stamp.bak")
        Copy-Item $FilePath $dest -Force
        Write-Log "Backup erstellt: $dest"
    }
}

function Download-Asset {
    param($Release, $Pattern)
    $asset = $Release.assets | Where-Object { $_.name -match $Pattern } | Select-Object -First 1
    if (-not $asset) { throw "Kein Asset gefunden, Pattern: $Pattern" }

    $dst = Join-Path $WorkDir $asset.name
    Write-Log "Lade herunter: $($asset.browser_download_url)"
    Invoke-WebRequest -Uri $asset.browser_download_url -OutFile $dst -UseBasicParsing
    return $dst
}

function Expand-IfArchive {
    param([string]$Path)
    if ([IO.Path]::GetExtension($Path) -eq ".zip") {
        $dir = Join-Path $WorkDir ([IO.Path]::GetFileNameWithoutExtension($Path))
        if (Test-Path $dir) { Remove-Item $dir -Recurse -Force }
        Expand-Archive -Path $Path -DestinationPath $dir
        return $dir
    }
    return $null
}

function Install-PluginFile {
    param([string]$Src, [string]$Target)

    $targetPath = Join-Path $PluginDir $Target
    Backup-File $targetPath
    Copy-Item $Src $targetPath -Force
    Write-Log "Installiert: $Target"
}

function Update-PluginViaChocolatey {
    param([string]$Pkg)

    $choco = Get-Command choco -ErrorAction SilentlyContinue
    if (-not $choco) { throw "Chocolatey nicht installiert." }

    Write-Log "Chocolatey-Update: $Pkg"
    Start-Process $choco.Source -ArgumentList "upgrade $Pkg -y --no-progress" -Wait -PassThru | Out-Null
}

# ================================
# === Ablauf =====================
# ================================

Ensure-Dirs
Set-Tls12

# Log-Rollover
if (Test-Path $LogFile) {
    $tooLarge = ((Get-Item $LogFile).Length -gt 5MB)
    if ($tooLarge) {
        Rename-Item $LogFile -NewName ("update_{0}.log" -f (Get-Date -Format "yyyyMMdd-HHmmss"))
    }
}

Write-Log "==== Start ===="

Stop-KeePass

foreach ($p in $Plugins) {
    $name = $p.Name
    Write-Log "Prüfe Plugin: ${name}"

    # Chocolatey-Plugins
    if ($p.ChocoPackage) {
        try {
            Update-PluginViaChocolatey $p.ChocoPackage
            $expected = Join-Path $PluginDir $p.TargetFile
            Write-Log ("Verifiziert: " + (Test-Path $expected))
        } catch {
            Write-Log "Fehler bei ${name}: $($_.Exception.Message)" "ERROR"
        }
        continue
    }

    # GitHub-Plugins
    try {
        $rel = Get-GitHubRelease -Repo $p.Repo -IncludePreRelease:$UsePreReleases
        if (-not $rel) {
            Write-Log "Kein Release für ${name}" "WARN"
            continue
        }

        $localFile = Join-Path $PluginDir $p.TargetFile
        $localHash = if (Test-Path $localFile) { (Get-FileHash $localFile).Hash } else { $null }

        $dl = Download-Asset -Release $rel -Pattern $p.AssetPattern
        $dir = Expand-IfArchive $dl
        $src = if ($dir) {
            (Get-ChildItem $dir -Recurse -Filter $p.TargetFile | Select-Object -First 1).FullName
        } else { $dl }

        $newHash = (Get-FileHash $src).Hash
        if ($localHash -eq $newHash) {
            Write-Log "${name} ist bereits aktuell."
            continue
        }

        Install-PluginFile -Src $src -Target $p.TargetFile
        Write-Log "${name} aktualisiert auf $($rel.tag_name)"
    }
    catch {
        Write-Log "Fehler bei ${name}: $($_.Exception.Message)" "ERROR"
    }
}

Start-KeePass
Write-Log "==== Fertig ===="

und hier das Script für den Task

# ==========================================
# KeePass Plugin Updater – Task Registration
# ==========================================

$TaskName   = "KeePass Plugin Updater"
$ScriptPath = 'C:\Program Files\KeePass Password Safe 2\Update-KeePassPlugins.ps1'
$WorkDir    = 'C:\Program Files\KeePass Password Safe 2'
$DailyTime  = [datetime]"09:15"
$UserId     = "$env:UserName"

# Action
$action = New-ScheduledTaskAction `
    -Execute 'powershell.exe' `
    -Argument "-NoProfile -ExecutionPolicy Bypass -File `"$ScriptPath`"" `
    -WorkingDirectory $WorkDir

# Trigger: Beim Anmelden + täglich
$trLogon = New-ScheduledTaskTrigger -AtLogOn
$trDaily = New-ScheduledTaskTrigger -Daily -At $DailyTime

# Principal: höchste Privilegien
$principal = New-ScheduledTaskPrincipal `
    -UserId $UserId `
    -LogonType Interactive `
    -RunLevel Highest

# Settings
$settings = New-ScheduledTaskSettingsSet `
    -StartWhenAvailable `
    -AllowStartIfOnBatteries `
    -DontStopIfGoingOnBatteries `
    -ExecutionTimeLimit (New-TimeSpan -Hours 1) `
    -RestartCount 2 `
    -RestartInterval (New-TimeSpan -Minutes 5)

# Task zusammenbauen
$task = New-ScheduledTask -Action $action -Trigger @($trLogon, $trDaily) -Principal $principal -Settings $settings

# Vorher löschen, falls vorhanden
if (Get-ScheduledTask -TaskName $TaskName -ErrorAction SilentlyContinue) {
    Unregister-ScheduledTask -TaskName $TaskName -Confirm:$false
}

# Registrieren
Register-ScheduledTask -TaskName $TaskName -InputObject $task

Write-Host "Task erfolgreich registriert."

Hinweis/Disclaimer: Dieses Setup wurde erfolgreich auf einem Windows 11 System angewendet. Es erfolgt keine Garantie oder Gewährleistung für Funktion, Vollständigkeit oder Eignung in anderen Umgebungen.

**Stand:** 14.02.2026

global vorbelegen wie Kontakte in Outlook Adresslisten gespeichert werden

Die Outlook Adresslisten funktionieren am besten, wenn die Datensätze (Kontakte) im gleichem Syntax abgespeichert werden.

Hierbei kann es z.B. Sinnvoll sein, wenn ein der Syntax für das Feld „Speichern unter“ und „anzeigen als“ wie in Abbildung global vorbelegt wird.

Um dies für den eigenen PC oder für einen Terminalserver festzulegen gibt es Makros, welche über Outlook die Registrie des Systems anpassen, so das der Syntax vorbelegt wird.

Das Makro für „Speichern unter“ :

Public Sub ChangeFileAs()
    Dim objOL As Outlook.Application
    Dim objNS As Outlook.NameSpace
    Dim objContact As Outlook.ContactItem
    Dim objItems As Outlook.Items
    Dim objContactsFolder As Outlook.MAPIFolder
    Dim obj As Object
    Dim strFileAs As String
    Dim myRegKey As String
    Dim myValue As String
    Dim myFileAs As String
    Dim myAnswer As Integer
    
On Error Resume Next

  ' get registry key to work with
  ' change the Outlook version # to match your version
  myRegKey = "HKEY_CURRENT_USER\Software\Microsoft\Office\15.0\Outlook\Contact\FileAsOrder"
  If myRegKey = "" Then Exit Sub
  'check if key exists
  If RegKeyExists(myRegKey) = True Then
    'key exists, read it
    myValue = RegKeyRead(myRegKey)
    If myValue = 14870 Then myFileAs = "Company"
    If myValue = 32791 Then myFileAs = "Last, First"
    If myValue = 32792 Then myFileAs = "Company (Last, First)"
    If myValue = 32793 Then myFileAs = "Last, First (Company)"
    If myValue = 32823 Then myFileAs = "First Last"
   
    
    'display result and ask if it should be changed
    myAnswer = MsgBox("The registry value for the key """ & _
               myRegKey & """is """ & myFileAs & vbCrLf & _
               "Do you want to change it?", vbYesNo)
  Else
    'key doesn't exist, ask if it should be created
    myAnswer = MsgBox("The registry key """ & myRegKey & _
               """ could not be found." & vbCr & vbCr & _
               "Do you want to create it?", vbYesNo)
  End If
  If myAnswer = vbYes Then
    'ask for new registry key value

    myValue = InputBox("Please enter new value: " & vbCrLf & _
    "14870 = Company" & vbCrLf & _
    "32791 = Last, First" & vbCrLf & _
    "32792 = Company (Last, First)" & vbCrLf & _
    "32793 = Last, First (Company)" & vbCrLf & _
    "32823 = First Last", myRegKey, myValue)
    If myValue <> "" Then
      RegKeySave myRegKey, myValue
      MsgBox "Registry key saved."
    End If    
  Else
  End If

' now that we've got the value of the default setting,
' we use it to set the value so all contacts are the same
    Set objOL = CreateObject("Outlook.Application")
    Set objNS = objOL.GetNamespace("MAPI")
    Set objContactsFolder = objNS.GetDefaultFolder(olFolderContacts)
    Set objItems = objContactsFolder.Items

    For Each obj In objItems
        'Test for contact and not distribution list
        If obj.Class = olContact Then
            Set objContact = obj

            With objContact

    If myValue = 14870 Then strFileAs = .CompanyName '"Company"
    If myValue = 32791 Then strFileAs = .LastNameAndFirstName '"Last, First"
    If myValue = 32792 Then strFileAs = .CompanyAndFullName '"Company (Last, First)"
    If myValue = 32793 Then strFileAs = .FullNameAndCompany '"Last, First (Company)"
    If myValue = 32823 Then strFileAs = .FullName '"First Last"

               .FileAs = strFileAs

                .Save
            End With
        End If

        Err.Clear
    Next

    Set objOL = Nothing
    Set objNS = Nothing
    Set obj = Nothing
    Set objContact = Nothing
    Set objItems = Nothing
    Set objContactsFolder = Nothing
End Sub

'reads the value for the registry key i_RegKey
'if the key cannot be found, the return value is ""
Function RegKeyRead(i_RegKey As String) As String
Dim myWS As Object

  On Error Resume Next
  'access Windows scripting
  Set myWS = CreateObject("WScript.Shell")
  'read key from registry
  RegKeyRead = myWS.RegRead(i_RegKey)
End Function

'sets the registry key i_RegKey to the
'value i_Value with type i_Type
'if i_Type is omitted, the value will be saved as string
'if i_RegKey wasn't found, a new registry key will be created
Sub RegKeySave(i_RegKey As String, _
               i_Value As String, _
      Optional i_Type As String = "REG_DWORD")
Dim myWS As Object

  'access Windows scripting
  Set myWS = CreateObject("WScript.Shell")
  'write registry key
  myWS.RegWrite i_RegKey, i_Value, i_Type

End Sub

'returns True if the registry key i_RegKey was found
'and False if not
Function RegKeyExists(i_RegKey As String) As Boolean
Dim myWS As Object

  On Error GoTo ErrorHandler
  'access Windows scripting
  Set myWS = CreateObject("WScript.Shell")
  'try to read the registry key
  myWS.RegRead i_RegKey
  'key was found
  RegKeyExists = True
  Exit Function
  
ErrorHandler:
  'key was not found
  RegKeyExists = False
End Function

Quelle 2017-03-08: https://www.slipstick.com/developer/bulk-change-fileas-format-contacts-default/

Das Makro für „anzeigen als“ :

Public Sub ChangeEmailDisplayName()
    Dim objOL As Outlook.Application
    Dim objNS As Outlook.NameSpace
    Dim objContact As Outlook.ContactItem
    Dim objItems As Outlook.Items
    Dim objContactsFolder As Outlook.MAPIFolder
    Dim obj As Object
    Dim strFirstName As String
    Dim strLastName As String
    Dim strFileAs As String

    On Error Resume Next

    Set objOL = CreateObject("Outlook.Application")
    Set objNS = objOL.GetNamespace("MAPI")
    Set objContactsFolder = objNS.GetDefaultFolder(olFolderContacts)
    Set objItems = objContactsFolder.Items

    For Each obj In objItems
        'Test for contact and not distribution list
        If obj.Class = olContact Then
            Set objContact = obj

          With objContact
    
          If .Email1Address <>"" Then
            ' Uncomment the  strFileAs line for the desired format
            ' Add the email address to any string using
            ' the following code:
            ' & " (" & .Email1Address & ")"
                 
             'Firstname Lastname (email address) format
             ' strFileAs = .FullName & " (" & .Email1Address & ")"
                
             'Lastname, Firstname format
              strFileAs = .LastNameAndFirstName
                
             'Company name (email address) format
             ' strFileAs = .CompanyName & " (" & .Email1Address & ")"
                 
             'Comapany Firstname Lastname (email address) format
             'the display name will have a leading space if
             'the contact doesn't have a company name
             'strFileAs = .CompanyName & " " & .FullName & " (" & .Email1Address & ")"
                

             'File As format
             'Does not support Company (Fullname) format. 
             'Only Company name is used in the display name
             'strFileAs = .FileAs
                
             .Email1DisplayName= strFileAs

             .Save
           End If
          End With
        End If

        Err.Clear
    Next

    Set objOL = Nothing
    Set objNS = Nothing
    Set obj = Nothing
    Set objContact = Nothing
    Set objItems = Nothing
    Set objContactsFolder = Nothing
End Sub

Quelle 2017-03-08: https://www.slipstick.com/outlook/contacts/bulk-change-outlook-contacts-email-display-name-format/

Ich habe beide Makro erfolgreich anwenden können.

Viel Spaß und vergesst nicht das Backup davor!!!

PowerShell Befehle für den Exchange Server

Da sich die PowerShell Befehle für den Exchange Server großer Beliebtheit erfreuen, habe ich mal ein paar neue Befehle hinzugefügt.

Exchange Server – ActiveSync

Liste aller ActiveSync Geräte

Get-ActiveSyncDevice | ft

ActiveSync-Statistik eines Postfaches

Get-ActiveSyncDeviceStatistics -mailbox "manuel.maliszewski"

Alle ActiveSync Geräte der OU „Ausgeschiedene User“ löschen

Get-ActiveSyncDevice -OrganizationalUnit "Ausgeschiedene User" | Remove-ActiveSyncDevice

Exchange Server – Datenbanken

Übersicht über Datenbanken und deren Größe

Get-MailboxDatabase -Status | ft name, databasesize

Übersicht über Datenbanken mit Informationen zu Retentation und Recoverable Quotas

Get-MailboxDatabase | Select Name, Server, MailboxRetention, Recoverab* |ft

Exchange Server – Postfächer

Übersicht der Postfächer einer Datenbank – Sortiert nach letztem Login mit den Feldern: Benutzername, Größe, Datum der letzten Anmeldung, Letzte Anmeldung

Get-Mailbox -Database "Berlin II - Datenbank II" | Get-MailboxStatistics | Sort LastLogonTime | ft DisplayName, TotalItemSize, LastLogonTime, LastLoggedOnUserAccount

Detailiert Übersicht eines Postfaches mit Unterordnern und dessen Größe

Get-MailboxFolderStatistics -identity "manuel.maliszewski" | ft FolderPath, FolderSize, ItemsInFolder, FolderAndSubfolderSize

Alle Postfächer mit Weiterleitung

Get-Mailbox | Where-Object { $_.ForwardingAddress –ne $null } | Select Name, ForwardingAddress

Alle Postfächer mit „Sende als“ und „volle Postfachberechtigung“

Get-Mailbox | Get-ADPermission | Where-Object { ($_.ExtendedRights -like "*send-as*") -and -not ($_.User -like "nt authority\self") }

Postfächer auf die der Benutzer „chilli“ volle Berechtigungen hat

Get-Mailbox | Get-MailboxPermission | Where-Object { ($_.AccessRights -eq "*fullaccess*") -and ($_.User -like "*chilli*") }

Exchange Server – Warteschlange

Warteschlange anzeigen auf Server S8K011

Get-Queue -Server S8K011

Warteschlangen Queue verschieben

./Move-TransportDatabase.ps1 –QueueDatabasepath “C:\Queue” –QueueDatabaseLoggingPath “D:\Queue”

Exchange Server – System

Alle Exchange-Dienste starten

Test-ServiceHealth | Select ServicesNotRunning | foreach { Start-Service $_.ServicesNotRunning }

Exchange-Dienste Status in Tabelle

Test-ServiceHealth | ft

Testet die Exchange Organisation auf Fehler

Test-SystemHealth

Exchange Server – Verschiedenes

Sprache aller Postfächer auf dem Server S8K011 auf Deutsch setzen

Get-Mailbox -Server S8K011 | Set-Mailbox -language de-DE

Sprache der Postfächer auf Server S8K012 anzeigen, nach Sprache sortieren und als Tabelle mit Namen und Sprache anzeigen

Get-Mailbox -Server S8K012 | sort Languages | ft name, Languages

Liste der Benutzer die den Abwensenheitsassistenten aktiviert haben

Get-Mailbox | Get-MailboxAutoReplyConfiguration | Where-Object { $_.AutoReplyState –eq “scheduled” }

Datenbank – RPC CAS abfragen

Get-MailboxDatabase -Server s8k011 | fl name, rpc\*

Datenbank-Index

Standardmäßig werden alle Datenbanken mit aktiviertem Index angelegt. in diesem Ordner wird der Index erstellt: %datenbankpfad%\CatalogData-Guid. Diesen kann man allerdings aktivieren:

Set-MailboxDatabase MailboxDatabaseName -IndexEnabled:$false

Erste Datenbank löschen

Beim Installieren von Exchange Server 2010 wird automatisch eine Datenbank angelegt. Diese Läst sich nicht über die Gui löschen, auch wenn alle Postfächer verschoben sind. Darum muss man die

System-Postfächer verschieben:

Get-mailbox -Arbitration | New-MoveRequest -TargetDatabase "Berlin I - Postfach I"

Danach muss man noch die Verschiebungsanforderungen löschen und die Datenbank ist entfernbar.

Quelle [2017-03-07]: http://chilltimes.de/2013/02/08/powershell-nutzliche-exchange-server-2010-befehle/

PowerShell ISE um Exchange Add-On erweitern

Wer den ISE der Powershell benutzt und einen Exchange bearbeiten will, muss vorher eine Verbindung aufbauen. Diese Arbeit kann man sich durch das hinzufügen der Exchange Add-Ons erleichtern.

Einfach eine PS1 Datei mit folgendem Inhalt starten und schon sind die Add-Ons des ISE erweitert.

$psISE.CurrentPowerShellTab.AddOnsMenu.SubMenus.Add(
    "Connect to Exchange @ Contoso", {
        $ExSession= New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri http://exserver.contoso.com/PowerShell/ -Authentication Kerberos
        Import-PSSession $ExSession
    },
    "Control+Alt+1"
)
$psISE.CurrentPowerShellTab.AddOnsMenu.SubMenus.Add(
    "Connect to Exchange On-Premise", {
        Add-PSSnapin Microsoft.Exchange.Management.PowerShell.E2010
        . $env:ExchangeInstallPath\bin\RemoteExchange.ps1
        Connect-ExchangeServer –auto
            },
    "Control+Alt+2"
)
$psISE.CurrentPowerShellTab.AddOnsMenu.SubMenus.Add(
    "Connect to Exchange Online", {
        $o365Cred= Get-Credential
        $o365Session= New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://ps.outlook.com/powershell/ -Credential $o365Cred -Authentication Basic -AllowRedirection
        Import-PSSession $o365Session
    },
    "Control+Alt+3"
)


Quelle [2017-03-08]: https://eightwone.com/2012/10/25/adding-exchange-shell-items-to-powershell-ise/