PowerShell logo

5 PowerShell-Snippets für den Microsoft 365 Admin-Alltag

Das sind die fünf Abfragen, die ich in Microsoft-365-Tenants am häufigsten brauche. Alle lesen nur, keine ändert etwas. Ich habe sie so geschrieben, dass man sie ohne Anpassung kopieren kann.

Vorbereitung

Das komplette Microsoft.Graph-Modul ist riesig und braucht ewig zum Installieren. Für diese Snippets reichen drei Teilmodule:

Install-Module Microsoft.Graph.Users, Microsoft.Graph.Reports, Microsoft.Graph.Identity.SignIns -Scope CurrentUser

Connect-MgGraph -Scopes 'User.Read.All','AuditLog.Read.All','UserAuthenticationMethod.Read.All'

Beim ersten Anmelden fragt Entra nach der Zustimmung für diese Rechte. Je nach Tenant-Einstellung muss das ein Admin bestätigen.

1. Wer hat sich seit 90 Tagen nicht angemeldet?

$cutoff = (Get-Date).AddDays(-90)

Get-MgUser -All -Property DisplayName,UserPrincipalName,AccountEnabled,SignInActivity |
  Where-Object {
    $_.AccountEnabled -and
    $_.SignInActivity.LastSignInDateTime -and
    $_.SignInActivity.LastSignInDateTime -lt $cutoff
  } |
  Select-Object DisplayName, UserPrincipalName,
    @{N='LastSignIn';E={$_.SignInActivity.LastSignInDateTime}} |
  Sort-Object LastSignIn

Das ist meine Liste für „Brauchen wir die Lizenz noch?“. Zwei Haken: SignInActivity gibt es nur mit Entra ID P1. Und Konten, die sich noch nie angemeldet haben, tauchen hier absichtlich nicht auf, weil sie kein Datum haben. Die prüfe ich separat, oft sind das vergessene Testkonten.

2. Aktive Benutzer ohne Lizenz

Get-MgUser -All -Property DisplayName,UserPrincipalName,AccountEnabled,AssignedLicenses |
  Where-Object { $_.AccountEnabled -and $_.AssignedLicenses.Count -eq 0 } |
  Select-Object DisplayName, UserPrincipalName

Hier landen Konten, bei denen beim Anlegen die Lizenz vergessen wurde, und Dienstkonten. Geteilte Postfächer erscheinen auch, die brauchen in der Regel keine Lizenz. Deren Anmeldung sollte aber deaktiviert sein. Wenn ein geteiltes Postfach hier als aktiv auftaucht, ist das der eigentliche Fund.

3. Gastkonten, neueste zuerst

Get-MgUser -All -Filter "userType eq 'Guest'" -Property DisplayName,Mail,CreatedDateTime,SignInActivity |
  Select-Object DisplayName, Mail, CreatedDateTime,
    @{N='LastSignIn';E={$_.SignInActivity.LastSignInDateTime}} |
  Sort-Object CreatedDateTime -Descending

Gäste sammeln sich über Teams schnell an. Wer seit einem Jahr nicht da war, fliegt bei mir nach Rücksprache raus.

4. Postfachgrößen als CSV

Install-Module ExchangeOnlineManagement -Scope CurrentUser   # einmalig
Connect-ExchangeOnline

Get-EXOMailbox -ResultSize Unlimited |
  Get-EXOMailboxStatistics |
  Select-Object DisplayName, TotalItemSize, ItemCount |
  Export-Csv -Path './mailbox-sizes.csv' -NoTypeInformation -Encoding utf8

Die EXO-Cmdlets sind bei vielen Postfächern deutlich schneller als die alten Get-Mailbox/Get-MailboxStatistics. Ich brauche das vor Migrationen und wenn jemand fragt, warum das Postfach voll ist.

5. Benutzer ohne MFA-Methode

Get-MgReportAuthenticationMethodUserRegistrationDetail -All |
  Where-Object { -not $_.IsMfaRegistered } |
  Select-Object UserPrincipalName, UserDisplayName, IsAdmin, MethodsRegistered

Das ist derselbe Bericht, den das Entra Admin Center unter Authentifizierungsmethoden → Benutzerregistrierungsdetails zeigt, nur als Liste. Er liefert alle Benutzer in einer Abfrage. Die Spalte IsAdmin zeigt sofort, ob ein Admin dabei ist. Das wäre dann zuerst zu klären.

Auch dieser Bericht braucht Entra ID P1. Ohne P1 geht es nur einzeln pro Benutzer, was bei großen Tenants dauert:

Get-MgUser -All -Filter 'accountEnabled eq true' -Property Id,UserPrincipalName |
  ForEach-Object {
    $methods = Get-MgUserAuthenticationMethod -UserId $_.Id |
      Where-Object { $_.AdditionalProperties['@odata.type'] -notmatch 'passwordAuthenticationMethod$' }
    if (-not $methods) { $_.UserPrincipalName }
  }

Warum PowerShell statt Portal

Alles davon geht auch im Portal. Mit Skript bekomme ich aber jedes Mal dieselbe Abfrage, kann das Ergebnis als CSV an den Kunden schicken und sehe beim nächsten Mal, was sich geändert hat.

Ähnliche Beiträge

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert