Hintergrund

Für einige Berechtigungen ist es hilfreich diese an die Mitgliedschaft in bestimmten Gruppen zu binden. Leider sind nicht alle Berechtigungen an eine Gruppe zu binden. Das bezieht sich zum Beispiel auf zugelassene Exchange Protokolle. Es könnte also sinnvoll sein eine AzureAD Gruppe zu verwenden dessen Mitglieder automatisch für die Nutzung von SMTP oder die Nutzung von IMAP/POP3 aktiviert werden ohne, dass man manuell in die Exchange Administration eintauchen muss. Diese Gruppe kann zum Beispiel auch aus dem OnPrem AD synchronisiert werden. Somit kann man dort auch direkt die Protokolle für einen Nutzer administrieren.

Ausblick

Es sind auch noch weitere Use-Cases denkbar so zum Beispiel die auomatische Verwaltung von delegierten Berechtigungen auf Shared Mailboxen. Wenn es für jede Shared Mailbox eine korrespondierende AzureAD Gruppe mit Self-Servie Group Membership Administration geben würde könnte man die Verwaltung der Zugriffe auf eine Shared Mailbox in die Hände des Owners dieser AzureAD Gruppe legen. Außerdem könnte man diese Berechtigungen durch die Access Review Funktion regemäßig prüfen.

Voraussetzungen

Um eine Automatiserung der Exchange Administration vorzunehmen gibt es verschiedene Wege. Dieser Artikel beschäftigt sich mit der Automatisierung durch die Nutzung von Azure Automate. Die Vorteile sind, dass man keine eigene Infrastruktur für das Ausführen von Runbooks betreiben muss und die übliche Azure Infrastruktur für das Monitoring verwenden kann. Weiterhin kann man innerhalb von Azure Automate sowohl OnPremise Runbooks als auch Runbooks die Online laufen sollen gemeinsam verwalten. Gegenüber den klassichen geplanten Tasks auf einem Service bietet Azure Automate außerdem den Vorteil die Protokoller aller Ausführungen einfach einzusehen. Ein weiterer Aspekt ist die Authentifierung von Zugriff des Skripts welches Dinge automatisieren soll auf die Resourcen die zur Anpassung von Konfigurationen erforderlich sind. Dies lässt sich OnPremise durch ein Zertifikat und ein Service Principal im AzureAD lösen. Im Fall von Azure Automate ist diese Identität durch Microsoft verwaltet. Ihr können direkt Berechtigungen die notwendig sind zugewiesen werden.

Azure Automate

Zunächst muss eine neue Azure Automate Instanz erstellt werden. Bei der Erstellung der Instanz wählen wir aus, dass eine System Assigned Identity verwendet werden soll. Diese werden wir später mit den notwendigen Berechtigungen ausstatten um Exchange Online Konfigurationen durchzuführen.

Berechtigungen

Die Zuweisung der notwendigen Berechtigungen geht nur teilweise per GUI. Die Zuweisung der API Berechtigungen lassen sich nur per Graph API erledigen. Um hier nicht zu viele Wege zu vermischen ist nachfolgend sowohl die Einrichtung der API-Berechtigungen als auch die Zuweisung der Azure AD Rolle per Graph API beschrieben.

Für einen einfachen Zugang zur Graph API bietet sich das Powershell Modul an. Wir gehen an dieser Stelle davon aus, dass dies bereits auf dem System installiert ist. Im ersten Schritt verbinden wir uns mit dem Graph API. Hier werden direkt die notwendigen Scopes angefragt. In diesem Fall möchten wir die folgenden Konfigurationen vornehmen:

  • Zuweisung einer Approlle zu einem ServicePrincipal (Application.ReadWrite.All)
  • Auslesen der vorhanden Azure AD Rollen (Directory.Read.All)
  • Zuweisen der Exchange Administrator Rolle (RoleManagement.ReadWrite.Directory)
  • Zuweisen der Graph Rolle (AppRoleAssignment.ReadWrite.All)

Mit dem nachfolgenden Befehl erfolgt die Anmeldung mit den notwendigen Berechtigungen:

1
Connect-MgGraph -Scopes Application.ReadWrite.All,AppRoleAssignment.ReadWrite.All,Directory.Read.All,RoleManagement.ReadWrite.Directory

Zuweisung der API-Berechtigungen EXO

Um der Identitiät unter der die Runbooks der Azure Automate Instanz laufen Berechtigungen zuzuweisen benöitgen wir zunächst deren Id. Diese lässt sich mit dem nachfolgenden Befehl abrufen. Dort ist der Name der Azure Automate Instanz einzutragen.

1
2
$ServicePrincipal = Get-MgServicePrincipal -All -Filter "DisplayName eq '<AzureAutomationInstanzName>'"
Write-Output "$($ServicePrincipal.DisplayName) has Id: $($ServicePrincipal.Id)"

Mögliche Berechtiungen sind Rollen auf einer spezfisichen App die ebenfall im AzureAD als solche registriert ist. In unserem Fall geht es um die Exchange Online API. Diese ist unter dem Namen “Office 365 Exchange Online” zu finden. Der nachfolgende Befehl gibt deren Id aus:

1
2
$EXOServicePrincipal = Get-MgServicePrincipal -Filter "displayName eq 'Office 365 Exchange Online'"
Write-Output "$($EXOServicePrincipal.DisplayName) has Id: $($EXOServicePrincipal.Id)"

Eine Anwendung kann mehr als eine Rolle zur Nutzung bereitstellen. In unserem Fall möchten wir unserer Runbook Identität die “Exchange.ManageAsApp” Berechtigun erteilen und wir interessieren uns für deren Id. Mit dem folgenden Befehl wird die Id ausgegeben:

1
2
$Approle = $EXOServicePrincipal.AppRoles.Where({$_.Value -eq 'Exchange.ManageAsApp'})
Write-Output "$($Approle.DisplayName) has Id: $($Approle.Id)"

Mit allen notwendigen Ids können wir nun die eigentliche Zuweisung erledigen. Der nachfolgende Befehl macht dies auf Basisd der vorher ermittelten Informationen:

1
New-MgServicePrincipalAppRoleAssignment -ServicePrincipalId $ServicePrincipal.Id -ResourceId $EXOServicePrincipal.Id -AppRoleId $Approle.Id -PrincipalId $ServicePrincipal.Id

Zuweisung der API-Berechtigungen Graph

Neben den Exchange Online Berechtigungen muss auch die Zustimmung zum auslesen der Mitgleider einer Gruppe gegeben werden.

1
2
3
4
5
6
$GraphServicePrincipal = Get-MgServicePrincipal -Filter "displayName eq 'Microsoft Graph'"

$ApproleAD = $GraphServicePrincipal.AppRoles.Where({$_.Value -eq 'GroupMember.Read.All'})
Write-Output "$($ApproleAD.DisplayName) has Id: $($ApproleAD.Id)"

New-MgServicePrincipalAppRoleAssignment -ServicePrincipalId $ServicePrincipal.Id -ResourceId $GraphServicePrincipal.Id -AppRoleId $ApproleAD.Id -PrincipalId $ServicePrincipal.Id

Zuweisung AzureAD Rolle

Nachdem alle Berechtigungen gesetzt worden sind, benötigt die Identität der Automate Instanz die passende Azure Active Directory Rolle. Deren Id müssen wir zunächst ermitteln. Das passiert mit dem nachfolgenden Befehl:

1
2
$ExchangeAdminRole = Get-MgDirectoryRole -Filter "DisplayName eq 'Exchange Administrator'"
Write-Output "$($ExchangeAdminRole.DisplayName) has Id: $($ExchangeAdminRole.Id)"

Mit der Id der Rolle und der Id der Identität unseres Automation Accounts können wir die Zuweisung vornehmen:

1
2
3
4
$DirObject = @{
  "@odata.id" = "https://graph.microsoft.com/v1.0/directoryObjects/$($ServicePrincipal.Id)"
  }
New-MgDirectoryRoleMemberByRef -DirectoryRoleId $ExchangeAdminRole.Id -BodyParameter $DirObject

Die erfolgreiche Zuweisung der Berechtigungen kann mit der ID im Azure Portal unter Enterprise-Apps nachverfolgt werden.

Installation benötigter Module in der Azure Automate Instanz

Damit unser Powershell-Script läuft, müssen wir zunächst alle erforderlichen Module installieren. Hierfür gehen wir in unsere Automate-Instanz und wählen auf der linken Seite den Tab Module. Anschließend können wir Module hinzufügen. Für die gruppenbasierte SMTP Aktivierung benötigen wir folgdende Module:

  1. Az.Accounts
  2. PackageManagement
  3. PowerShellGet
  4. ExchangeOnlineManagement
  5. Microsoft.Graph.Authentication
  6. Microsoft.Graph.Groups

Alle Module müssen in der Version 5.1 installiert werden.

Erstellung des Powershell Runbooks in Azure Automate

Nachdem unsere Module bereit stehen, können wir uns an die Erstellung des Powerautomate Scriptes setzen. Hierfür erstellen wir in unserer Instanz unter dem Tab Runbooks ein neues Runbook. Die Laufzeitversion beträgt 5.1, der Typ ist Powershell.

Anschließend klicken wir auf bearbeiten und erstellen unser Script. Bei den nachfolgenden Script muss der Tenantname und die ID der Gruppe aller SMTP Nutzenden ersetzt werden. Anschließend können wir unser Script im Berarbeitungsmenü unter der Auswahl Testbereich testen.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# Verbindung zu Exchange Online herstellen
Connect-ExchangeOnline -ManagedIdentity -Organization <Tenantname>.onmicrosoft.com
Write-Output "Connected to Exchange Online"

# Verbindung zu Graph herstellen
Connect-AzAccount -Identity
$token = Get-AzAccessToken -ResourceUrl "https://graph.microsoft.com"
Connect-MgGraph -AccessToken $token.Token
Write-Output "Connected to Graph"

# Variable mit allen Mailboxen erzeugen
$mailboxes = Get-EXOCasMailbox -ResultSize Unlimited
Write-Output "Retrieved all mailboxes"

# Abrufen aller Mitglieder der Gruppe "SMTP_Active" über GraphAPI
$groupMembers = Get-MgGroupMember -GroupId <Gruppen-ID>
Write-Output "Retrieved all group members from SMTP_Active"

# Für jedes Mitglied überprüfen, ob SMTP eingeschaltet ist, wenn nein oder null -> einschalten
foreach ($member in $groupMembers) {
    $mailbox = $mailboxes | Where-Object {$_.Name -eq $member.Id}
    if ($mailbox.SmtpClientAuthenticationDisabled -eq $true -or $mailbox.SmtpClientAuthenticationDisabled -eq $null) {
        Set-CASMailbox -Identity $mailbox.Identity -SmtpClientAuthenticationDisabled $false
        Write-Output "Enabled SMTP authentication for mailbox with ID: $($mailbox.Identity)"
    }
}

Write-Output "Checked all Group mailboxes and enabled SMTP where necessary"

# Alle Mailboxen aus der Liste löschen die in der Gruppe "SMTP_Active" sind
$mailboxes = $mailboxes | Where-Object { $_.Name -notin $groupMembers.Id }
Write-Output "Removed all mailboxes in the SMTP_Active group from the list"

# Für jedes verbeleibende Mitglied der Liste überprüfen, ob SMTP eingeschaltet ist, und wenn ja, deaktivieren
foreach ($mailbox in $mailboxes) {
    if ($mailbox.SmtpClientAuthenticationDisabled -eq $false -or $mailbox.SmtpClientAuthenticationDisabled -eq $null) {
        Set-CASMailbox -Identity $mailbox.Identity -SmtpClientAuthenticationDisabled $true
        Write-Output "Disabling SMTP authentication for mailbox with ID: $($mailbox.Identity)"
    }
}

Write-Output "Checked all remaining mailboxes and disabled SMTP where necessary"

# Trennen der Verbindung
Disconnect-ExchangeOnline
Disconnect-MgGraph
Write-Output "Disconnected"

Liveschaltung des Scriptes

Zuletzt wird das Runbook veröffentlicht und eine stündliche Ausführung konfiguriert.