M365 Organisationseinstellungen per PowerShell ⏱ 12 Min.

M365 Organisationseinstellungen per PowerShell

M365 Tenant härten per PowerShell & Graph

Jeder kennt die Situation bei einem frischen M365 Tenant: Du klickst dich durch ein Admin Center nach dem anderen und stellst alles so ein, wie es passend erscheint. Dabei verlierst du Zeit, denn jedes Portal lädt erst, baut seine Kacheln auf und springt bei jedem Wechsel neu an. Schneller geht es über PowerShell.

Manuelle Klicks im Microsoft 365 Admin Center kosten aber nicht nur Zeit. Sie erzeugen Konfigurationsfehler und lassen sich bei einem Audit nicht reproduzieren. Wer Tenants professionell verwaltet, definiert den Ist-Zustand deshalb über PowerShell.

Die Verwaltung der Organisationseinstellungen läuft über das Microsoft Graph PowerShell SDK, das die Graph API direkt anspricht. Für reine Identitätsaufgaben steht zusätzlich das szenariofokussierte Modul Microsoft Entra PowerShell bereit. Es baut auf dem Graph SDK auf und bringt mit Enable-EntraAzureADAlias einen Kompatibilitätsmodus mit, falls noch betagte AzureAD-Skripte im Bestand liegen.

Voraussetzungen & Berechtigungen

Das Microsoft Graph PowerShell SDK arbeitet nach dem Least-Privilege-Prinzip mit granularen Scopes. Du deklarierst die benötigten Scopes exakt, sonst bricht der Befehl mit einem Autorisierungsfehler ab. Microsoft empfiehlt für Graph und Entra PowerShell den Einsatz von PowerShell 7. Bleibst du bei Windows PowerShell 5.1, brauchst du .NET Framework 4.7.2 und ein aktuelles PowerShellGet.

Ein vorhandener Scope allein reicht in Microsoft Graph nicht immer aus. Für delegierte Zugriffe auf das organization-Objekt dokumentiert Microsoft zusätzlich unterstützte Entra-Rollen. Ohne passende Rolle liefert auch eine formell korrekte Verbindung keine Schreibberechtigung. Zum Lesen des Organisations-Objekts genügen Rollen wie Global Reader, Directory Readers oder Security Reader. Für Änderungen an der authorizationPolicy verlangt das System den Privileged Role Administrator als kleinste unterstützte Rolle, kombiniert mit dem Scope Policy.ReadWrite.Authorization.

Eine zweite Einschränkung betrifft Get-MgOrganization. Anwendungen mit dem Scope User.Read lesen aus dem Organisations-Objekt nur id, displayName und verifiedDomains. Alle übrigen Eigenschaften kommen als null zurück. Für eine belastbare Dokumentation des Organisationsprofils deklarierst du deshalb mindestens Organization.Read.All.

# Nur lesen
Connect-MgGraph -Scopes "Organization.Read.All", "Policy.Read.All"

# Für Änderungen an den Tenant-Kontakten
Connect-MgGraph -Scopes "Organization.ReadWrite.All"

Grundlegende Tenant-Informationen und Kontaktadressen

Ein fehlerfreies Organisationsprofil sorgt dafür, dass kritische Systemwarnungen von Microsoft im Sicherheitsvorfall sofort beim zuständigen Team ankommen. Stehen dort veraltete Adressen, landen diese Benachrichtigungen oft in verwaisten Postfächern ehemaliger Mitarbeiter, und die IT verliert wertvolle Reaktionszeit.

Die hinterlegten Adressen prüfst du über das Organisations-Cmdlet:

# Kontaktadressen des Tenants prüfen
Get-MgOrganization | Select-Object DisplayName, TechnicalNotificationMails,
    SecurityComplianceNotificationMails, SecurityComplianceNotificationPhones,
    MarketingNotificationEmails

Liefert die Abfrage veraltete Adressen, korrigierst du den Zustand über die Tenant-ID und ein anschließendes Update. Die Graph API erlaubt Schreibzugriffe auf dem Organisations-Objekt nur für klar definierte Felder: marketingNotificationEmails, privacyProfile, securityComplianceNotificationMails, securityComplianceNotificationPhones und technicalNotificationMails.

# Technische Kontakte setzen (Tenant-ID fürs Update ermitteln)
$TenantId = (Get-MgOrganization).Id
Update-MgOrganization -OrganizationId $TenantId `
    -TechnicalNotificationMails @("security-team@deine-domain.de")

Organisationsprofil: Standort und Basiswerte prüfen

Die geografischen Basiswerte legen den Standard-Rechenzentrumstandort und die Systemsprache deines Tenants fest. Diese Werte wirken auf DSGVO-relevante Datenresidenz und auf die Abrechnung.

Nicht jeder sichtbare Basiswert lässt sich nachträglich ändern. Für Country/Region dokumentiert Microsoft ausdrücklich, dass der Wert nach der Tenant-Erstellung fixiert bleibt. Er bestimmt verfügbare Dienste, Steuern und Währung. Passt die Region nicht mehr, bleibt nur ein neuer Account mit neuer Subscription und eine Datenmigration. Lege diese Werte deshalb bei der Ersteinrichtung als feste Architekturentscheidung fest.

# Standort, Sprache und Basis-IDs des Tenants
Get-MgOrganization | Select-Object DisplayName, Country, CountryLetterCode,
    PreferredLanguage, CreatedDateTime, DefaultUsageLocation

# Verifizierte und Standard-Domänen auflisten
(Get-MgOrganization).VerifiedDomains |
    Select-Object Name, IsDefault, IsInitial, Type

Security Defaults: Die Basis-Verteidigungslinie prüfen

Für kleinere Tenants ohne Premium-Lizenzen sind die Security Defaults die einzige integrierte Möglichkeit, eine Multifaktor-Authentifizierung für alle Konten zu erzwingen. Sind sie deaktiviert und existiert keine eigene Conditional-Access-Richtlinie, bleibt der Tenant offen für Passwort-Spraying.

# Prüfen ob Security Defaults aktiv sind
Get-MgPolicyIdentitySecurityDefaultEnforcementPolicy | Select-Object IsEnabled, Description

Ab Entra ID P1 ist Conditional Access der präzisere Weg, weil sich MFA dann pro Benutzergruppe, Standort, Risiko und Client steuern lässt. Beachte den Übergang bei der MFA-Verwaltung: Microsoft hat die alte Per-User-MFA-Verwaltung über die Service Settings ausgemustert, die Steuerung der Methoden gehört in die Authentication Methods Policy. Security Defaults und eine Conditional-Access-Richtlinie schließen sich gegenseitig aus, du aktivierst entweder das eine oder das andere.

Dienste: Globale Kalenderfreigabe prüfen

Die globale Freigaberichtlinie in Exchange Online legt fest, wie viele Termindetails Anwender maximal mit externen Partnern teilen dürfen. Zu lockere Standardwerte geben komplette Termininhalte nach außen frei. Angreifer nutzen das gezielt, um interne Projektabläufe auszukundschaften.

Die Prüfung ist nur belastbar, wenn du die Reichweite der Freigaberichtlinien berücksichtigst. Eine Sharing Policy wirkt erst, wenn sie einem Postfach zugewiesen ist. Hat ein Postfach keine eigene Zuweisung, greift automatisch die Default Sharing Policy.

# Globale Kalenderfreigabe-Richtlinien prüfen
Connect-ExchangeOnline
Get-SharingPolicy | Select-Object Name, Enabled, Domains

Bei der ersten Änderung bestimmter Exchange-Organisationsobjekte verlangt Exchange Online eine Vorbedingung. Microsoft nennt dafür das Cmdlet Enable-OrganizationCustomization. Solange diese Aktivierung fehlt, scheitern Änderungsversuche an den unvorbereiteten Standardobjekten.

# Exchange Online einmalig für Organisationsanpassungen vorbereiten
Enable-OrganizationCustomization

Sicherheit und Datenschutz: App-Berechtigungen der Benutzer

Ein primärer Angriffsweg in der Cloud ist OAuth-Consent-Phishing. Angreifer bringen Benutzer über gefälschte Mails dazu, einer App weitreichende Leserechte zu erteilen. Ein Passwortdiebstahl entfällt, weil die App über ein vom Nutzer bewilligtes Token arbeitet. Diese Angriffsfläche steuerst du über die Autorisierungsrichtlinie.

Microsoft führt dort zentrale Standards zusammen, darunter allowUserConsentForRiskyApps, allowInvitesFrom, allowedToSignUpEmailBasedSubscriptions und allowedToUseSSPR. Für die Härtung prüfst du allowUserConsentForRiskyApps. Der Standardwert ist false, und Microsoft rät ausdrücklich, ihn auf false zu belassen. Andernfalls kompromittieren riskante Anwendungen die Umgebung direkt über OAuth.

Parallel prüfst du permissionGrantPoliciesAssigned. Ein leeres Array schaltet die Benutzereinwilligung für Apps komplett ab. Ein zugewiesener Built-in-Wert wie ManagePermissionGrantsForSelf.microsoft-user-default-low erlaubt Einwilligungen unter einer eng begrenzten Richtlinie. In vielen Tenants steht hier noch der Legacy-Wert ManagePermissionGrantsForSelf.microsoft-user-default-legacy, den du gezielt auf die Low-Variante anhebst.

# Self-Service-Rechte der Standardbenutzer prüfen
Get-MgPolicyAuthorizationPolicy |
    Select-Object -ExpandProperty DefaultUserRolePermissions |
    Select-Object AllowedToCreateApps, PermissionGrantPoliciesAssigned

Zusammenarbeit: M365-Gruppen-Erstellung einschränken

Darf jeder Anwender beliebig Teams und SharePoint-Websites erstellen, wächst der Tenant in unkontrolliertes Datenchaos, und du verlierst den Überblick über Datenablagen und Berechtigungen. Die Steuerung der M365-Gruppen-Erstellung liegt in den Directory Settings der Vorlage Group.Unified.

Diese tenantweiten Gruppen-Settings liegen weiterhin im Beta-Endpunkt der Graph API. Du sprichst sie über die Beta-Cmdlets aus dem Submodul Microsoft.Graph.Beta.Identity.DirectoryManagement an, sonst findest du die Vorlage Group.Unified nicht zuverlässig:

# Submodul laden und Gruppen-Settings abfragen
Import-Module Microsoft.Graph.Beta.Identity.DirectoryManagement
Connect-MgGraph -Scopes "Directory.Read.All"
Get-MgBetaDirectorySetting |
    Where-Object DisplayName -eq "Group.Unified" |
    Select-Object -ExpandProperty Values

Achte beim Beta-Submodul auf den Versionsstand. Lädt deine Session schon eine andere Version von Microsoft.Graph.Authentication, scheitert der Import mit einem Assembly-Konflikt. Bring in dem Fall alle Microsoft.Graph-Module auf denselben Stand und starte eine frische PowerShell-Session.

Willst du ohne Beta-Modul auskommen, liest du dieselbe Einstellung über die REST-Schiene, die nur das Authentication-Modul braucht:

# Alternative ohne Beta-Submodul
(Invoke-MgGraphRequest -Method GET -Uri "https://graph.microsoft.com/v1.0/groupSettings").value |
    Where-Object displayName -eq "Group.Unified" |
    ForEach-Object { $_.values }

Eine leere Ausgabe bedeutet, dass der Tenant die Vorlage noch nie angepasst hat. Dann greift der Default EnableGroupCreation = true, jeder Standardnutzer darf also Gruppen anlegen.

Steht EnableGroupCreation auf True, blockierst du die Funktion per Update und delegierst das Erstellungsrecht über GroupCreationAllowedGroupId an eine definierte IT-Sicherheitsgruppe. Das zwingt Anwender, neue Arbeitsräume über einen geregelten IT-Prozess anzufordern. Für den Schreibzugriff brauchst du den Scope Policy.ReadWrite.DirectorySettings oder Directory.ReadWrite.All.

Identitäten: Gastnutzer-Einladungen (B2B) regulieren

Kann jeder Mitarbeiter externe Gast-Accounts anlegen, füllt sich das Verzeichnis mit unüberwachten Konten. Angreifer kapern verwaiste Gastkonten für laterale Bewegungen im Netzwerk.

# Prüfen, ob Standardnutzer Gäste einladen dürfen
Get-MgPolicyAuthorizationPolicy |
    Select-Object -ExpandProperty DefaultUserRolePermissions |
    Select-Object AllowedToInviteGuest

Der Wert allowInvitesFrom steht in den meisten Cloud-Umgebungen per Default auf everyone. Ziehst du das auf adminsAndGuestInviters zurück, vergibst du das Einladungsrecht nur noch an dedizierte Manager oder an die Rolle Guest Inviter. Den Berechtigungsumfang der Gäste selbst begrenzt du zusätzlich über guestUserRoleId, etwa mit der Rolle Restricted Guest User.

Netzwerke: Tenant-übergreifender Zugriff (Cross-Tenant Access)

Arbeiten Anwender in fremden Tenants, steuern die Cross-Tenant-Access-Richtlinien das Vertrauen in externe MFA-Nachweise. Falsch konfiguriert öffnest du Einfallstore aus schwach geschützten Partner-Umgebungen. Ein sicherer Ansatz fordert MFA zwingend im eigenen Tenant an.

Den Default-Block liest du am saubersten über das dedizierte Cmdlet statt über die Expand-Variante:

# Standardrichtlinien für B2B-Zugriff abrufen
Get-MgPolicyCrossTenantAccessPolicy | Select-Object -ExpandProperty Default

Für gezielte Partner ergänzt du organisationsspezifische Richtlinien über Get-MgPolicyCrossTenantAccessPolicyPartner und konfigurierst dort, ob du dem MFA-Claim des Partners vertraust.

Sicherheit & Datenschutz: Legacy-Zugriffe per MSOL PowerShell blockieren

Die MSOnline-Cmdlets griffen über einen alten Dienstendpunkt auf den Tenant zu, der modernes Conditional Access umgeht. Mit blockMsolPowerShell sperrst du diesen benutzerbasierten Zugriff auf den Legacy-Endpunkt. Microsoft Entra Connect und Microsoft Graph bleiben davon unberührt.

Der Schreibzugriff auf die Autorisierungsrichtlinie ist abgesichert. Du brauchst dafür den Scope Policy.ReadWrite.Authorization, ein reiner Lese-Scope wie Directory.Read.All quittiert den Versuch mit einem 403. Zusätzlich verlangt das Objekt delegiert mindestens die Rolle Privileged Role Administrator. Fehlt sie, lehnt Graph den Schreibzugriff auch bei korrektem Scope ab.

# Mit Schreib-Scope verbinden und Scope prüfen
Connect-MgGraph -Scopes "Policy.ReadWrite.Authorization"
(Get-MgContext).Scopes

# Benutzerzugriff über den MSOnline-Endpunkt sperren
$params = @{
    blockMsolPowerShell = $true
}
Update-MgPolicyAuthorizationPolicy -BodyParameter $params

Das MSOnline-Modul ist seit geraumer Zeit abgeschaltet, der Schalter wirkt deshalb als zusätzliche Absicherung gegen Restzugriffe auf den alten Endpunkt, nicht mehr als alleinige Maßnahme. Setze ihn als Teil deiner Defense-in-Depth. Prüfe parallel über die Sign-in-Logs, ob noch Skripte oder Service-Accounts den Legacy-Pfad ansteuern, denn nur so erkennst du Automatisierungen, die nach dem Setzen des Schalters ins Leere laufen.

Sicherheit & Datenschutz: Self-Service-Käufe

Standardbenutzer erwerben über Self-Service-Käufe eigenständig Lizenzen für Produkte wie Power BI Pro, Power Automate oder Project. Das untergräbt die zentrale Budgetkontrolle, verletzt unter Umständen Compliance-Vorgaben und begünstigt unregulierte Schatten-IT. Steuern lässt sich diese Funktion tenantweit ausschließlich über das Modul MSCommerce.

Das Modul gehört nicht zum Graph SDK und wird separat aus der PowerShell Gallery installiert. Für die Anmeldung brauchst du einen Billing- oder Global-Administrator.

# Modul einmalig installieren
Install-Module -Name MSCommerce -Scope CurrentUser -Force

# Danach verbinden und abfragen
Connect-MSCommerce
Get-MSCommerceProductPolicies -PolicyId AllowSelfServicePurchase |
    Sort-Object ProductName | Format-Table ProductName, PolicyValue

Die Richtlinie gilt strikt pro Produkt, einen globalen Schalter gibt es nicht. Du bewertest jedes freigegebene Produkt einzeln und deaktivierst es gezielt über Update-MSCommerceProductPolicy. Neue Microsoft-Produkte sind nach Veröffentlichung oft direkt wieder freigegeben. Plane bis zu 72 Stunden ein, bis Änderungen über die Synchronisationsprozesse in allen Diensten greifen. Eine feinere Steuerung pro Benutzer oder pro Sicherheitsgruppe bietet Microsoft an dieser Stelle nicht. Bestehende Abos kannst du übernehmen, Benutzer verschieben oder die Abonnements kündigen.

Weitere Härtungsmaßnahmen per PowerShell

Die folgenden Einstellungen gehören in dieselbe Bestandsaufnahme, weil sie denselben Tenant betreffen und sich ebenfalls skriptgesteuert verwalten lassen. Der Vorteil gegenüber der GUI bleibt derselbe: Du liest den Ist-Zustand reproduzierbar aus und schreibst den Soll-Zustand im selben Skript zurück, statt dich durch verstreute Portale zu klicken. Die Tabelle ordnet jede Maßnahme ihrem Bereich zu und nennt das Cmdlet zum Lesen sowie das passende Gegenstück zum Setzen.

BereichMaßnahmeLesen / Schreiben
IdentitätAuthentifizierungsmethoden, Nachfolger der Per-User-MFA-VerwaltungGet-MgPolicyAuthenticationMethodPolicy 

Update-MgPolicyAuthenticationMethodPolicy
IdentitätConditional Access, etwa Block Legacy Auth und MFA für AdminsGet-MgIdentityConditionalAccessPolicy

New-MgIdentityConditionalAccessPolicy, Update-MgIdentityConditionalAccessPolicy
IdentitätNamed Locations für standortbasierte RegelnGet-MgIdentityConditionalAccessNamedLocation

New-MgIdentityConditionalAccessNamedLocation
IdentitätApp-Registrierung durch Standardnutzer abschalten (AllowedToCreateApps)Get-MgPolicyAuthorizationPolicy

Update-MgPolicyAuthorizationPolicy
IdentitätTenant-Erstellung durch Standardnutzer unterbinden (AllowedToCreateTenants)Get-MgPolicyAuthorizationPolicy

Update-MgPolicyAuthorizationPolicy
IdentitätSichtbarkeit anderer Benutzer einschränken (AllowedToReadOtherUsers)Get-MgPolicyAuthorizationPolicy

Update-MgPolicyAuthorizationPolicy
Apps und ConsentRiskante Enterprise Apps und veraltete Berechtigungen prüfenGet-MgServicePrincipal, Get-MgOauth2PermissionGrant

Remove-MgOauth2PermissionGrant
Apps und ConsentBenutzerzuweisung pro Enterprise App erzwingen (AppRoleAssignmentRequired)Get-MgServicePrincipal

Update-MgServicePrincipal
B2B und GeräteCross-Tenant-Zugriff und Tenant Restrictions v2Get-MgPolicyCrossTenantAccessPolicyDefault

Update-MgPolicyCrossTenantAccessPolicyDefault
B2B und GeräteGeräteregistrierung und Entra-Join-BerechtigungenGet-MgPolicyDeviceRegistrationPolicy

Update-MgPolicyDeviceRegistrationPolicy

Die drei Werte aus der Autorisierungsrichtlinie setzt du nicht einzeln, sondern gebündelt über die verschachtelte Eigenschaft defaultUserRolePermissions:

# App-Registrierung und Tenant-Erstellung für Standardnutzer abschalten
Connect-MgGraph -Scopes "Policy.ReadWrite.Authorization"
$params = @{
    defaultUserRolePermissions = @{
        allowedToCreateApps    = $false
        allowedToCreateTenants = $false
    }
}
Update-MgPolicyAuthorizationPolicy -BodyParameter $params

Welche Zeilen für deinen Tenant greifen, hängt von Lizenz und Workloads ab. Für die Consent- und Conditional-Access-Themen brauchst du jeweils die passenden Policy-Scopes mit Schreibrecht, etwa Policy.ReadWrite.ConditionalAccess oder Policy.ReadWrite.Authorization. Ein reiner Lese-Scope quittiert jeden Schreibversuch mit einem 403. Exchange- und SharePoint-Werte erfordern zudem eine eigene Verbindung über Exchange Online PowerShell beziehungsweise die SharePoint-Online-Verwaltung.

Den Ist-Zustand dokumentieren

Für ein anstehendes Audit exportierst du die Einstellungen in eine maschinenlesbare Datei. Der JSON-Export liefert eine strukturierte Basis für spätere Systemvergleiche.

# Organisationseinstellungen als JSON sichern
Get-MgOrganization |
    Select-Object DisplayName, TechnicalNotificationMails, Country, PreferredLanguage |
    ConvertTo-Json |
    Out-File ".\Org-Settings_$(Get-Date -Format 'yyyy-MM-dd').json"

Configuration-as-Code: Microsoft365DSC

Der JSON-Export liefert eine Momentaufnahme. Sobald du mehrere Tenants betreust oder einen definierten Soll-Zustand dauerhaft halten willst, stößt das an Grenzen. Hier setzt Microsoft365DSC an, ein Open-Source-Modul auf Basis von PowerShell Desired State Configuration.

Statt einzelne Werte abzufragen, beschreibst du die komplette Tenant-Konfiguration als Code. Microsoft365DSC exportiert den Ist-Zustand über Workloads wie Entra ID, Exchange Online und Intune hinweg in eine zusammenhängende Konfiguration. Diese Datei wird zu deiner Quelle der Wahrheit. Weicht der Tenant später davon ab, erkennt das Modul diese Drift und meldet sie. Auf Wunsch rollt es den definierten Stand erneut aus und gleicht die Abweichung an. Damit baust du einen neuen Tenant nicht mehr von Hand auf, sondern reichst eine geprüfte Konfiguration ein.

Technisch läuft die kompilierte Konfiguration über den Local Configuration Manager eines Agenten, also einer Maschine oder eines Containers. Der kommuniziert über die Microsoft-365-APIs zurück in den Tenant und braucht deshalb Internetzugang.

# Modul installieren und auf den aktuellen Stand bringen
Install-Module -Name Microsoft365DSC -Force
Update-M365DSCModule
Hinweis
Microsoft365DSC meldet standardmäßig anonyme Daten über erkannte Drifts und Fehlertypen zurück, inklusive der Stadt des Absenders. Sensible Inhalte überträgt es nicht. In regulierten Umgebungen schaltest du das ab, bevor du produktiv gehst:

# Telemetrie deaktivieren
Set-M365DSCTelemetryOption -Enabled $false


Für den Einstieg lohnt ein Blick auf die offizielle Dokumentation und den YouTube-Kanal des Projekts, dort findest du fertige Beispiele für Export, Vergleich und Deployment.

Fazit

Die Konfiguration von Microsoft 365 über PowerShell schließt die Lücken, die unübersichtliche Webmenüs hinterlassen. Skripte überführen administrative Prozesse in eine reproduzierbare Struktur und dokumentieren den Systemzustand verlässlich. Die alten Administrationsmodule haben ihr End-of-Life erreicht, der Weg führt über das Microsoft Graph PowerShell SDK und Microsoft Entra PowerShell.

Die Härtung eines Tenants verlangt Präzision. Globale Richtlinien wie die Kalenderfreigabe greifen erst nach Zuweisung zu den Postfächern. Basiswerte wie die Tenant-Region lassen sich nachträglich nicht korrigieren. Wer den App-Consent differenziert konfiguriert, Self-Service-Käufe produktgenau überwacht und Legacy-Zugriffe sperrt, schützt die Umgebung vor Schatten-IT. Die API-Endpunkte hinter den Cmdlets bleiben stabil. Ein sauber geschriebenes Skript liefert auf Knopfdruck den Nachweis für die nächste Sicherheitsüberprüfung.

Teilen:
Noch keine Kommentare

Sei der Erste und starte die Diskussion mit einem hilfreichen Beitrag.

Kommentar hinterlassen

Dein Beitrag wird vor der Veröffentlichung kurz geprüft — fachlich, respektvoll und auf den Punkt ist hier genau richtig.

E-Mail Adresse wird nicht veröffentlicht.