Microsoft 365 | PowerShell Security Audit - Teil 2: Mail-Schutz, Collaboration & Geräte ⏱ 11 Min.

Microsoft 365 | PowerShell Security Audit - Teil 2: Mail-Schutz, Collaboration & Geräte

Mail-Authentifizierung, Defender, SharePoint, Teams, Intune & App-Berechtigungen

In Teil 1 dieser Serie hast Du das Fundament geprüft: MFA-Methoden, Conditional Access, privilegierte Rollen, Gäste und die Exchange-Postfächer, die Prüfpunkte 1 bis 29.

Eine gehärtete Identität schützt aber nur die Eingangstür. Die eigentlichen Daten liegen in Mail, SharePoint, OneDrive und Teams, und der Weg dorthin führt über den E-Mail-Bedrohungsschutz, die Freigabe-Einstellungen, die Geräte-Compliance und die App-Berechtigungen.

Teil 2 nimmt sich genau diese Schicht vor. Die folgenden Prüfpunkte 30 bis 58 decken die E-Mail-Authentifizierung per DNS, Microsoft Defender for Office 365, die Datenfreigabe in SharePoint und OneDrive, die Teams-Konfiguration, die Gerätesteuerung aus Intune und die Anwendungs- und OAuth-Governance ab.

Die Voraussetzungen und Authentifizierungs-Stolperfallen für die Module sind in Teil 1 beschrieben, der saubere Modul-Stand und die Connect-Hinweise gelten unverändert.

eMail-Authentifizierung (DNS)

30. DKIM-Signatur-Status

DKIM signiert ausgehende Nachrichten kryptografisch, eine gefälschte Signatur fällt beim Empfänger auf. Entscheidend ist nicht nur der DNS-Eintrag, sondern die tatsächliche Aktivierung in Exchange Online. Eine Domain ohne aktives DKIM landet bei modernen Empfängern schnell im Spam.

Connect-ExchangeOnline -ShowBanner:$false
Get-DkimSigningConfig | Select-Object Name, Enabled, Selector1CNAME, Selector2CNAME | Format-Table -AutoSize

31. SPF-Record

SPF prüft den sendenden Server gegen einen veröffentlichten DNS-Eintrag und schützt vor Envelope-Spoofing. Fehlt der Record oder endet er nicht mit einem harten -all, akzeptieren empfangende Server auch nicht autorisierte Absender. Ausgelesen wird der TXT-Eintrag jeder akzeptierten Domain direkt per DNS.

# Get-AcceptedDomain aus der EXO-Session, Resolve-DnsName aus Windows
$domains = (Get-AcceptedDomain).DomainName
foreach ($d in $domains) {
    $spf = (Resolve-DnsName -Name $d -Type TXT -ErrorAction SilentlyContinue |
        Where-Object { $_.Strings -match "v=spf1" }).Strings
    [PSCustomObject]@{ Domain = $d; SPF = ($spf -join " ") }   # Befund: leer oder ohne "-all"
}

32. DMARC-Policy

DMARC setzt SPF und DKIM in eine durchsetzbare Richtlinie um und liefert Reporting. Erst p=reject weist Empfänger an, gefälschte Mails abzulehnen, p=none protokolliert nur. Maßgeblich ist der _dmarc-TXT-Record jeder Domain.

foreach ($d in (Get-AcceptedDomain).DomainName) {
    $dmarc = (Resolve-DnsName -Name "_dmarc.$d" -Type TXT -ErrorAction SilentlyContinue |
        Where-Object { $_.Strings -match "v=DMARC1" }).Strings
    [PSCustomObject]@{ Domain = $d; DMARC = ($dmarc -join " ") }   # Befund: kein Record oder p=none
}

Microsoft Defender for Office 365

33. Anti-Phishing und Impersonation Protection

Lizenz:Microsoft Defender for Office 365 Plan 1 oder Plan 2

Angreifer nutzen kleine Abweichungen in Namen (CEO-Fraud), um Rechnungsfreigaben zu erzwingen, der Schaden liegt schnell im sechsstelligen Bereich. Die Impersonation-Eigenschaften EnableTargetedUserProtection und EnableTargetedDomainsProtection existieren nur mit Defender for Office 365. Stehen sie auf False, greift der Schutz für benannte Führungskräfte und Domains nicht.

Connect-ExchangeOnline -ShowBanner:$false
Get-AntiPhishPolicy |
    Select-Object Name, EnableTargetedUserProtection, EnableTargetedDomainsProtection, TargetedUsersToProtect |
    Format-Table

Lizenz:Microsoft Defender for Office 365 Plan 1 oder Plan 2

Safe Links prüft URLs zum Klickzeitpunkt, nicht nur beim Nachrichteneingang. Angreifer nutzen Time-of-Click-Angriffe: Die URL ist beim Empfang harmlos und wird Stunden später auf eine Phishing-Seite umgeleitet. Wichtig ist, dass der Schutz für Mail und Teams gleichermaßen scharf geschaltet ist.

Connect-ExchangeOnline -ShowBanner:$false
Get-SafeLinksPolicy | Select-Object Name, EnableSafeLinksForEmail, EnableSafeLinksForTeams, ScanUrls | Format-Table

35. Safe Attachments

Lizenz:Microsoft Defender for Office 365 Plan 1 oder Plan 2

Safe Attachments ergänzt die signaturbasierte Erkennung durch Sandboxing in isolierten Umgebungen und fängt so Zero-Day-Malware ab, die klassische Scanner nicht kennen. Maßgeblich ist, ob überhaupt eine Richtlinie existiert und welche Aktion bei einem Treffer greift (Block, Replace oder Dynamic Delivery).

Connect-ExchangeOnline -ShowBanner:$false
Get-SafeAttachmentPolicy | Select-Object Name, Enable, Action, Redirect | Format-Table

SharePoint Online und OneDrive

Lizenz: SharePoint Online Plan 1

 Dateifreigaben akkumulieren über Jahre zu einem Compliance-Risiko, jeder anonyme Gastlink ist ein Datenleck auf Abruf. Get-PnPFileSharingLink braucht eine konkrete Datei-Referenz über -Identity und enumeriert keine ganze Site, der frühere -FileUrl ist abgekündigt. Deshalb iterierst Du über die Bibliothek und prüfst Datei für Datei, gefundene Links widerrufst Du über Remove-PnPFileSharingLink.

# Modul: PnP.PowerShell
Connect-PnPOnline -Url "https://deintenant.sharepoint.com/sites/projekt" -Interactive -ClientId $pnpClientId
$items = Get-PnPListItem -List "Dokumente" -PageSize 500 | Where-Object { $_.FileSystemObjectType -eq "File" }
foreach ($item in $items) {
    $ref = $item.FieldValues["FileRef"]
    Get-PnPFileSharingLink -Identity $ref |
        Where-Object { $_.Link.Scope -eq "anonymous" } |
        Select-Object @{N="Datei";E={$ref}}, @{N="Scope";E={$_.Link.Scope}}, @{N="Typ";E={$_.Link.Type}}
}

Steht der Standard-Link-Typ auf AnonymousAccess, entstehen täglich neue Datenlecks ohne böse Absicht. Das Zielbild ist Internal (organisationsweiter Link) oder Direct (bestimmte Personen). Der Nutzer soll bewusst entscheiden müssen, wenn eine Datei das Unternehmen verlässt.

Connect-SPOService -Url "https://deintenant-admin.sharepoint.com"
Get-SPOTenant | Select-Object SharingCapability, DefaultSharingLinkType, RequireAnonymousLinksExpireInDays | Format-List
# Variante ohne SPO-Modul, falls PnP verbunden: Get-PnPTenant | Select-Object SharingCapability, DefaultSharingLinkType

38. Externe Freigabe-Stufe SharePoint

SharingCapability legt fest, ob extern überhaupt geteilt werden darf und ob anonyme Links erlaubt sind. ExternalUserAndGuestSharing ist die offenste Stufe und Voraussetzung für anonyme Links. Restriktiver und je nach Schutzbedarf angemessen sind ExternalUserSharingOnly, ExistingExternalUserSharingOnly oder Disabled.

Connect-SPOService -Url "https://deintenant-admin.sharepoint.com"
Get-SPOTenant | Select-Object SharingCapability   # Befund: ExternalUserAndGuestSharing ohne Begruendung

39. OneDrive Freigabe-Stufe

OneDrive hat eine eigene Freigabe-Stufe, die strenger sein kann als SharePoint, aber oft ungeprüft auf dem SharePoint-Wert mitläuft. Persönliche Ablagen mit offener externer Freigabe sind ein verbreiteter Abflusskanal. OneDriveSharingCapability zeigt den tatsächlichen Stand.

Connect-SPOService -Url "https://deintenant-admin.sharepoint.com"
Get-SPOTenant | Select-Object OneDriveSharingCapability

Ein anonymer Link ohne Ablaufdatum bleibt unbegrenzt gültig und wird beliebig weitergeleitet, ein erzwungener Ablauf begrenzt das Zeitfenster. RequireAnonymousLinksExpireInDays gibt die Tage bis zum Ablauf an, der Wert 0 bedeutet kein erzwungener Ablauf.

Connect-SPOService -Url "https://deintenant-admin.sharepoint.com"
Get-SPOTenant | Select-Object RequireAnonymousLinksExpireInDays   # Befund: 0 (kein Ablauf)

41. Legacy-Authentifizierung in SharePoint

LegacyAuthProtocolsEnabled hält alte, nicht tokenbasierte Authentifizierung für SharePoint offen, oft für Drittanbieter-Tools, und diese Protokolle umgehen Conditional Access. True ist ein Befund, sofern kein Altsystem zwingend darauf angewiesen ist.

Connect-SPOService -Url "https://deintenant-admin.sharepoint.com"
Get-SPOTenant | Select-Object LegacyAuthProtocolsEnabled   # Befund, wenn True

42. Versionierung in SharePoint und OneDrive

Versionierung ist kein Backup, aber die erste Verteidigungslinie gegen logische Datenveränderung und Ransomware-Verschlüsselung. Ohne ausreichende Versionshistorie ist eine Wiederherstellung nach einem Angriff nicht möglich. EnableMinimumVersionRequirement zeigt, ob auf Tenant-Ebene eine Mindestversionierung erzwungen wird.

Connect-SPOService -Url "https://deintenant-admin.sharepoint.com"
Get-SPOTenant | Select-Object EnableMinimumVersionRequirement

43. Zugriff von nicht verwalteten Geräten

Ohne Steuerung greift jedes private, ungemanagte Gerät per Browser und Sync-Client auf SharePoint und OneDrive zu, inklusive Download und Offline-Kopie. ConditionalAccessPolicy regelt das tenantweit: AllowFullAccess lässt alles zu, AllowLimitedAccess erlaubt nur Web ohne Download, BlockAccess sperrt ganz. Für BYOD ist mindestens die eingeschränkte Stufe sinnvoll.

Connect-SPOService -Url "https://deintenant-admin.sharepoint.com"
Get-SPOTenant | Select-Object ConditionalAccessPolicy   # Befund: AllowFullAccess bei BYOD-Szenarien

Microsoft Teams

44. Teams Federation und External Access

Microsoft Teams ist standardmäßig für offene Föderation konfiguriert. Der Master-Schalter AllowFederatedUsers steht auf True, und bei leerer AllowedDomains-Liste kann jeder externe Teams-Nutzer mit verwaltetem Konto Deine Mitarbeiter anschreiben. Den früheren Schalter AllowPublicUsers für die Skype-Consumer-Föderation gibt es nicht mehr, Microsoft hat diese Interoperabilität zum 05.05.2025 eingestellt. Maßgeblich sind heute AllowFederatedUsers und AllowTeamsConsumer, die Härtung ist eine Allow-List genehmigter Partner.

Connect-MicrosoftTeams
$fed = Get-CsTenantFederationConfiguration
[PSCustomObject]@{
    AllowFederatedUsers = $fed.AllowFederatedUsers
    AllowTeamsConsumer  = $fed.AllowTeamsConsumer
    AllowedDomains      = ($fed.AllowedDomains | Out-String).Trim()
    BlockedDomains      = ($fed.BlockedDomains | Out-String).Trim()
} | Format-List

[SCREENSHOT: Teams Admin Center > Benutzer > Externer Zugriff]

45. Teams Meeting Policies: Lobby-Bypass

Erlaubt die Standardrichtlinie jedem Teilnehmer den Wartebereich zu umgehen, haben externe Dritte sofort Zugriff auf Meeting-Chat und geteilte Inhalte. Der schwächste Wert für AutoAdmittedUsers ist Everyone. Sicher sind EveryoneInCompany, InvitedUsers oder OrganizerOnly.

Connect-MicrosoftTeams
Get-CsTeamsMeetingPolicy | Select-Object Identity, AutoAdmittedUsers, AllowAnonymousUsersToStartMeeting | Format-Table

46. Anonyme Meeting-Teilnahme

AllowAnonymousUsersToJoinMeeting entscheidet, ob anonyme Teilnehmer überhaupt einem Meeting beitreten dürfen. In Kombination mit einem offenen Lobby-Bypass landen Fremde direkt im Meeting. Steht der Wert auf True, gehört er gegen das Schutzbedürfnis abgewogen.

Connect-MicrosoftTeams
Get-CsTeamsMeetingPolicy | Select-Object Identity, AllowAnonymousUsersToJoinMeeting | Format-Table

47. Gastzugriff in Teams

AllowGuestUser steuert tenantweit, ob Gäste den Teams-Client überhaupt nutzen dürfen. Gäste sehen sonst Chats, Dateien und Kanäle, oft mehr als für die ursprüngliche Zusammenarbeit nötig. Der Schalter gehört zur Guest-Governance zusammen mit den Einlade- und Freigaberegeln.

Connect-MicrosoftTeams
Get-CsTeamsClientConfiguration | Select-Object AllowGuestUser

48. Teams App-Berechtigungsrichtlinien

Apps in Teams sind Integrationen mit eigenem Berechtigungsmodell und API-Zugriff auf Tenant-Daten. Eine offene App-Permission-Policy lässt beliebige Drittanbieter-Apps zu. Die Typ-Werte AllowedAppList oder BlockedAppList zeigen, ob die Auswahl auf geprüfte Apps begrenzt ist.

Connect-MicrosoftTeams
Get-CsTeamsAppPermissionPolicy |
    Select-Object Identity, DefaultCatalogAppsType, GlobalCatalogAppsType, PrivateCatalogAppsType | Format-Table

Geräte und Endpoint

49. Intune Device Compliance und veraltete Geräte

Deine Conditional-Access-Richtlinien verlangen ein konformes Gerät, doch ein Gerät behält seinen Status oft, wenn es wochenlang nicht synchronisiert hat. Der serverseitige Filter auf lastSyncDateTime ist zulässig, Graph unterstützt für diese Eigenschaft lt und gt. Geräte ohne Sync seit 30 Tagen verfälschen die Aussagekraft der Compliance-Richtlinien.

Connect-MgGraph -Scopes "DeviceManagementManagedDevices.Read.All" -NoWelcome
$cutoffIso = (Get-Date).AddDays(-30).ToString("yyyy-MM-ddTHH:mm:ssZ")
Get-MgDeviceManagementManagedDevice -Filter "lastSyncDateTime lt $cutoffIso" -All |
    Select-Object DeviceName, OperatingSystem, ComplianceState, LastSyncDateTime | Sort-Object LastSyncDateTime

50. Inaktive und verwaiste Entra-ID-Geräte

Ein gestohlenes oder verlorenes Notebook behält sein Entra-ID-Objekt und die zugehörigen Zertifikate. Geräteobjekte ohne Anmeldung seit über 90 Tagen gehören deaktiviert, um Token-Missbrauch über alte Hardware auszuschließen.

Connect-MgGraph -Scopes "Device.Read.All" -NoWelcome
$cut = (Get-Date).AddDays(-90)
Get-MgDevice -All -Property DisplayName, ApproximateLastSignInDateTime, DeviceId |
    Where-Object { $null -ne $_.ApproximateLastSignInDateTime -and $_.ApproximateLastSignInDateTime -lt $cut } |
    Select-Object DisplayName, DeviceId, ApproximateLastSignInDateTime | Sort-Object ApproximateLastSignInDateTime

51. Nicht konforme Geräte

Wenn Deine CA-Policies ein konformes Gerät verlangen, entscheidet der Compliance-Status direkt über den Zugriff. Ein nicht konformes Gerät mit aktivem Zugriff bedeutet entweder eine Lücke in der Policy oder ein echtes Sicherheitsproblem. Gezählt wird alles, dessen ComplianceState nicht compliant ist.

Connect-MgGraph -Scopes "DeviceManagementManagedDevices.Read.All" -NoWelcome
Get-MgDeviceManagementManagedDevice -All -Property DeviceName, ComplianceState, OperatingSystem |
    Where-Object { $_.ComplianceState -ne "compliant" } |
    Select-Object DeviceName, OperatingSystem, ComplianceState

52. Geräteverschlüsselung

Ein unverschlüsseltes Notebook ist bei Verlust oder Diebstahl ein DSGVO-Vorfall, die Daten sind ohne weiteres lesbar. Verwaltete Geräte, deren IsEncrypted auf False steht, gehören auf eine erzwungene BitLocker-Richtlinie.

Connect-MgGraph -Scopes "DeviceManagementManagedDevices.Read.All" -NoWelcome
Get-MgDeviceManagementManagedDevice -All -Property DeviceName, IsEncrypted, OperatingSystem |
    Where-Object { $_.IsEncrypted -eq $false } |
    Select-Object DeviceName, OperatingSystem, IsEncrypted

Anwendungen, OAuth und App-Governance

Nutzer gewähren Drittanbieter-Apps oft unbedacht Zugriff. Dieser Illicit Consent Grant braucht weder Passwort noch MFA, die App greift über die Graph API direkt auf Postfächer oder SharePoint zu. Gefiltert wird auf delegierte Grants mit weitreichenden Leserechten, für ein reines Audit genügt der Lese-Scope.

Connect-MgGraph -Scopes "Application.Read.All","DelegatedPermissionGrant.Read.All" -NoWelcome
$grants = Get-MgOauth2PermissionGrant -All
$grantReport = foreach ($g in $grants) {
    $app = Get-MgServicePrincipal -ServicePrincipalId $g.ClientId
    [PSCustomObject]@{ AppDisplayName = $app.DisplayName; Scope = $g.Scope; ConsentType = $g.ConsentType }
}
$grantReport | Where-Object { $_.Scope -match "Mail.Read|Files.ReadWrite.All" } | Format-Table

54. Enterprise Apps mit Anwendungsberechtigungen

Gefährlicher als delegierte Rechte sind Application Permissions: App-Rollen wie Mail.Read, Files.ReadWrite.All oder Directory.ReadWrite.All exponieren den Tenant auch ohne kompromittierten Nutzer. Aufgelöst werden die App-Rollen-Zuweisungen gegen Microsoft Graph, gemeldet wird jede hochprivilegierte Anwendungsberechtigung.

Connect-MgGraph -Scopes "Application.Read.All" -NoWelcome
$graphSp = Get-MgServicePrincipal -Filter "appId eq '00000003-0000-0000-c000-000000000000'"
$roleMap = @{}; $graphSp.AppRoles | ForEach-Object { $roleMap[$_.Id] = $_.Value }
$risky = @("Mail.Read","Mail.ReadWrite","Files.ReadWrite.All","Directory.ReadWrite.All","Application.ReadWrite.All","RoleManagement.ReadWrite.Directory")
foreach ($sp in (Get-MgServicePrincipal -All)) {
    Get-MgServicePrincipalAppRoleAssignment -ServicePrincipalId $sp.Id |
        Where-Object { $_.ResourceId -eq $graphSp.Id -and $roleMap[$_.AppRoleId] -in $risky } |
        Select-Object @{N="App";E={$sp.DisplayName}}, @{N="Permission";E={$roleMap[$_.AppRoleId]}}
}

Dürfen Endanwender Apps selbst Berechtigungen erteilen, verliert die IT die Kontrolle über den Datenabfluss. Ein zugewiesener Wert wie managePermissionGrantsForSelf.microsoft-user-default-low bedeutet aktives User-Consent. Rufe Get-MgPolicyAuthorizationPolicy ohne -Property auf, sonst liefert das SDK die DefaultUserRolePermissions nicht zuverlässig.

Connect-MgGraph -Scopes "Policy.Read.All" -NoWelcome
$auth = Get-MgPolicyAuthorizationPolicy
[PSCustomObject]@{
    PolicyId         = $auth.Id
    UserConsentState = $auth.DefaultUserRolePermissions.PermissionGrantPoliciesAssigned -join ", "
} | Format-List   # Befund, wenn "managePermissionGrantsForSelf" enthalten ist

Nach dem Abschalten von User Consent brauchen Nutzer einen Weg, Apps anzufordern. Der Admin Consent Workflow leitet Anfragen an benannte Prüfer, fehlt er, umgehen Nutzer die Einschränkung oder Schatten-IT entsteht am Helpdesk vorbei. IsEnabled soll auf True stehen, sobald User-Consent eingeschränkt ist.

Connect-MgGraph -Scopes "Policy.Read.All" -NoWelcome
(Get-MgPolicyAdminConsentRequestPolicy).IsEnabled   # Soll: True

57. Ablaufende Client Secrets

App-Registrierungen bilden das Rückgrat für Automatisierungen. Ein ablaufendes Secret legt die App lahm, ein kompromittiertes verwaistes Secret gibt Angreifern dauerhaften API-Zugriff. Interessant sind die Secrets mit weniger als 30 Tagen Restlaufzeit, sie zeigen drohende Ausfälle und nebenbei ungenutzte Integrationen.

Connect-MgGraph -Scopes "Application.Read.All" -NoWelcome
$apps = Get-MgApplication -All
$secretReport = foreach ($app in $apps) {
    foreach ($pw in $app.PasswordCredentials) {
        [PSCustomObject]@{ AppName = $app.DisplayName; EndDate = $pw.EndDateTime; DaysLeft = ($pw.EndDateTime - (Get-Date)).Days }
    }
}
$secretReport | Where-Object { $_.DaysLeft -lt 30 } | Sort-Object DaysLeft

58. Ablaufende Zertifikate

Zertifikate sind die zweite Anmeldeart neben Secrets und laufen genauso ab, stehen aber in KeyCredentials statt in PasswordCredentials. Ein eigener Prüfpunkt verhindert, dass eine zertifikatsbasierte Integration unbemerkt ausläuft.

Connect-MgGraph -Scopes "Application.Read.All" -NoWelcome
$apps = Get-MgApplication -All
$certReport = foreach ($app in $apps) {
    foreach ($cert in $app.KeyCredentials) {
        [PSCustomObject]@{ AppName = $app.DisplayName; EndDate = $cert.EndDateTime; DaysLeft = ($cert.EndDateTime - (Get-Date)).Days }
    }
}
$certReport | Where-Object { $_.DaysLeft -lt 30 } | Sort-Object DaysLeft

Fazit nach weiteren 28 Audits

Mit dem E-Mail-Bedrohungsschutz, den Freigabe-Einstellungen, der Geräte-Compliance und der App-Governance ist die Schicht geprüft, über die Daten den Tenant verlassen oder Schadcode hineinkommt. SPF, DKIM und DMARC schützen Deine Domain vor Missbrauch, Defender for Office 365 fängt verzögerte Phishing-Ziele und Zero-Day-Malware ab, und die Kontrolle über anonyme Links, Teams-Föderation und OAuth-Berechtigungen schließt die häufigsten Abflusskanäle.

Was jetzt noch fehlt, ist die Klammer aus Governance und Nachweisbarkeit. Teil 3 prüft die Gruppen- und Daten-Governance mit DLP, Aufbewahrung und Vertraulichkeitsbezeichnungen, den erweiterten Bedrohungsschutz mit Quarantäne- und Tenant-Allow-Block-Listen sowie die Protokollierung und Überwachung vom Unified Audit Log bis zum Secure Score. Das sind die Prüfpunkte 59 bis 80, inklusive zwölf zusätzlicher Checks für Compliance und Lebenszyklus.

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.