PowerShell-ReferenzPowerShell Reference
Modulübersicht, Verbindungsbeispiele und eine einsatzbereite Skriptsammlung für Entra ID, Microsoft 365 und Automatisierung.Module overview, connection examples, and a ready-to-run script collection for Entra ID, Microsoft 365, and automation.
Module und VerbindungsmusterModules and connection patterns
| ModulModule | InstallationInstall command | VerbindungConnect command | Erforderliche RechteRequired permissions |
|---|---|---|---|
| Microsoft.GraphMicrosoft.Graph |
Install-Module Microsoft.Graph -Scope CurrentUserInstall-Module Microsoft.Graph -Scope CurrentUser
|
Connect-MgGraph -Scopes "User.Read.All"Connect-MgGraph -Scopes "User.Read.All"
|
Graph Scopes und passende Entra-RollenGraph scopes and matching Entra roles |
| ExchangeOnlineManagementExchangeOnlineManagement |
Install-Module ExchangeOnlineManagement -Scope CurrentUserInstall-Module ExchangeOnlineManagement -Scope CurrentUser
|
Connect-ExchangeOnline -UserPrincipalName admin@contoso.comConnect-ExchangeOnline -UserPrincipalName admin@contoso.com
|
Exchange Admin oder delegierte RollenExchange admin or delegated roles |
| Microsoft.Online.SharePoint.PowerShellMicrosoft.Online.SharePoint.PowerShell |
Install-Module Microsoft.Online.SharePoint.PowerShell -Scope CurrentUserInstall-Module Microsoft.Online.SharePoint.PowerShell -Scope CurrentUser
|
Connect-SPOService -Url https://contoso-admin.sharepoint.comConnect-SPOService -Url https://contoso-admin.sharepoint.com
|
SharePoint AdminSharePoint admin |
| PnP.PowerShellPnP.PowerShell |
Install-Module PnP.PowerShell -Scope CurrentUserInstall-Module PnP.PowerShell -Scope CurrentUser
|
Connect-PnPOnline -Url https://contoso.sharepoint.com -InteractiveConnect-PnPOnline -Url https://contoso.sharepoint.com -Interactive
|
SharePoint-Berechtigungen oder App-RegistrierungSharePoint permissions or app registration |
| MicrosoftTeamsMicrosoftTeams |
Install-Module MicrosoftTeams -Scope CurrentUserInstall-Module MicrosoftTeams -Scope CurrentUser
|
Connect-MicrosoftTeamsConnect-MicrosoftTeams
|
Teams Admin oder passende Workload-RolleTeams admin or matching workload role |
| Microsoft.PowerApps.Administration.PowerShellMicrosoft.PowerApps.Administration.PowerShell |
Install-Module Microsoft.PowerApps.Administration.PowerShell -Scope CurrentUserInstall-Module Microsoft.PowerApps.Administration.PowerShell -Scope CurrentUser
|
Add-PowerAppsAccountAdd-PowerAppsAccount
|
Power Platform AdminPower Platform admin |
| AzAz |
Install-Module Az -Scope CurrentUserInstall-Module Az -Scope CurrentUser
|
Connect-AzAccountConnect-AzAccount
|
Azure RBAC und Subscription-ZugriffAzure RBAC and subscription access |
Installiere Module bevorzugt im CurrentUser-Kontext und sperre Versionsstände in produktiven Automatisierungen, damit Runbooks und geplante Aufgaben reproduzierbar bleiben.Prefer installing modules in the CurrentUser scope and pin versions for production automation so runbooks and scheduled tasks remain reproducible.
Microsoft Graph PowerShellMicrosoft Graph PowerShell
Das Microsoft.Graph-Modul ist in Submodule aufgeteilt. Für kleine Admin-Workflows genügt oft das Meta-Modul; für schlanke Runbooks ist die Installation einzelner Submodule wie Microsoft.Graph.Users oder Microsoft.Graph.Identity.DirectoryManagement sinnvoll.The Microsoft.Graph module is split into submodules. For small admin workflows, the meta module is often enough; for lean runbooks, installing targeted submodules such as Microsoft.Graph.Users or Microsoft.Graph.Identity.DirectoryManagement is sensible.
| Sub-ModulSubmodule | Typische CmdletsTypical cmdlets | EinsatzUse case |
|---|---|---|
| Microsoft.Graph.UsersMicrosoft.Graph.Users |
Get-MgUser, New-MgUserGet-MgUser, New-MgUser
|
BenutzerverwaltungUser management |
| Microsoft.Graph.GroupsMicrosoft.Graph.Groups |
Get-MgGroup, New-MgGroupGet-MgGroup, New-MgGroup
|
Gruppen und MitgliedschaftenGroups and memberships |
| Microsoft.Graph.Identity.SignInsMicrosoft.Graph.Identity.SignIns |
Get-MgAuditLogSignIn, Get-MgRiskyUserGet-MgAuditLogSignIn, Get-MgRiskyUser
|
Audit, Sign-ins, Identity ProtectionAudit, sign-ins, identity protection |
| Microsoft.Graph.DeviceManagementMicrosoft.Graph.DeviceManagement |
Get-MgDeviceManagementManagedDeviceGet-MgDeviceManagementManagedDevice
|
Intune und Managed DevicesIntune and managed devices |
| Microsoft.Graph.ApplicationsMicrosoft.Graph.Applications |
Get-MgApplication, Get-MgServicePrincipalGet-MgApplication, Get-MgServicePrincipal
|
App-Registrierungen und Service PrincipalsApp registrations and service principals |
Install-Module Microsoft.Graph -Scope CurrentUser
Import-Module Microsoft.Graph
Connect-MgGraph -Scopes "User.Read.All","Group.Read.All","AuditLog.Read.All"
Get-MgContext
Connect-MgGraph -TenantId $TenantId -ClientId $AppId -CertificateThumbprint $Thumbprint
Get-MgContext
Get-MgApplication -Top 5
$clientSecret = ConvertTo-SecureString $env:GRAPH_CLIENT_SECRET -AsPlainText -Force
$credential = New-Object System.Management.Automation.PSCredential($AppId, $clientSecret)
Connect-MgGraph -TenantId $TenantId -ClientSecretCredential $credential
Get-MgServicePrincipal -Top 5
Find-MgGraphCommand -Command Get-MgUser
Find-MgGraphCommand -Uri "/users/{id}/memberOf"
Find-MgGraphPermission -SearchString "Conditional Access"
-
Nutze
Select-MgProfile -Name betanur, wenn ein beta-Endpunkt tatsächlich benötigt wirdUseSelect-MgProfile -Name betaonly when a beta endpoint is actually required -
Arbeite mit
-Propertyund-Allbewusst, um nur relevante Daten abzurufenUse-Propertyand-Alldeliberately to fetch only relevant data -
Nutze
Invoke-MgGraphRequestfür Endpunkte, die im SDK noch nicht sauber modelliert sindUseInvoke-MgGraphRequestfor endpoints not yet modeled well in the SDK -
Prüfe den aktiven Kontext mit
Get-MgContextvor langen ScriptsCheck the active context withGet-MgContextbefore long-running scripts
Exchange OnlineExchange Online
ExchangeOnlineManagement ist das Standardmodul für Exchange Online. Viele Cmdlets sind REST-basiert und deutlich performanter als ältere Remote-PowerShell-Sitzungen.ExchangeOnlineManagement is the standard module for Exchange Online. Many cmdlets are REST-backed and significantly faster than legacy remote PowerShell sessions.
Install-Module ExchangeOnlineManagement -Scope CurrentUser
Connect-ExchangeOnline -UserPrincipalName admin@contoso.com
Get-ConnectionInformation
| CmdletCmdlet | ZweckPurpose | SyntaxSyntax |
|---|---|---|
Connect-ExchangeOnlineConnect-ExchangeOnline
|
Verbindung zu Exchange Online herstellenConnect to Exchange Online |
Connect-ExchangeOnline -UserPrincipalName admin@contoso.comConnect-ExchangeOnline -UserPrincipalName admin@contoso.com
|
Disconnect-ExchangeOnlineDisconnect-ExchangeOnline
|
Sitzung sauber schließenClose the session cleanly |
Disconnect-ExchangeOnline -Confirm:$falseDisconnect-ExchangeOnline -Confirm:$false
|
Get-EXOMailboxGet-EXOMailbox
|
Benutzer- und Spezialpostfächer lesenRead user and special mailboxes |
Get-EXOMailbox -ResultSize UnlimitedGet-EXOMailbox -ResultSize Unlimited
|
Get-MailboxGet-Mailbox
|
Legacy-kompatible MailboxabfragenLegacy-compatible mailbox queries |
Get-Mailbox -ResultSize UnlimitedGet-Mailbox -ResultSize Unlimited
|
New-MailboxNew-Mailbox
|
Postfach erstellenCreate a mailbox |
New-Mailbox -Name "Room 101" -RoomNew-Mailbox -Name "Room 101" -Room
|
Set-MailboxSet-Mailbox
|
Postfach konfigurierenConfigure a mailbox |
Set-Mailbox -Identity user@contoso.com -HiddenFromAddressListsEnabled $trueSet-Mailbox -Identity user@contoso.com -HiddenFromAddressListsEnabled $true
|
Remove-MailboxRemove-Mailbox
|
Postfach entfernenRemove a mailbox |
Remove-Mailbox -Identity user@contoso.comRemove-Mailbox -Identity user@contoso.com
|
Get-MailboxStatisticsGet-MailboxStatistics
|
Größe und letzte Anmeldung ermittelnRetrieve size and last logon |
Get-MailboxStatistics -Identity user@contoso.comGet-MailboxStatistics -Identity user@contoso.com
|
Get-MailboxPermissionGet-MailboxPermission
|
Full Access und andere Rechte prüfenInspect mailbox permissions |
Get-MailboxPermission -Identity shared@contoso.comGet-MailboxPermission -Identity shared@contoso.com
|
Add-MailboxPermissionAdd-MailboxPermission
|
Mailboxrechte vergebenGrant mailbox permissions |
Add-MailboxPermission -Identity shared@contoso.com -User admin@contoso.com -AccessRights FullAccessAdd-MailboxPermission -Identity shared@contoso.com -User admin@contoso.com -AccessRights FullAccess
|
Remove-MailboxPermissionRemove-MailboxPermission
|
Mailboxrechte entfernenRemove mailbox permissions |
Remove-MailboxPermission -Identity shared@contoso.com -User admin@contoso.com -AccessRights FullAccessRemove-MailboxPermission -Identity shared@contoso.com -User admin@contoso.com -AccessRights FullAccess
|
Get-RecipientPermissionGet-RecipientPermission
|
Send As prüfenCheck Send As permissions |
Get-RecipientPermission -Identity shared@contoso.comGet-RecipientPermission -Identity shared@contoso.com
|
Add-RecipientPermissionAdd-RecipientPermission
|
Send As vergebenGrant Send As |
Add-RecipientPermission -Identity shared@contoso.com -Trustee admin@contoso.com -AccessRights SendAsAdd-RecipientPermission -Identity shared@contoso.com -Trustee admin@contoso.com -AccessRights SendAs
|
Get-DistributionGroupGet-DistributionGroup
|
Verteilergruppen lesenRead distribution groups |
Get-DistributionGroup -ResultSize UnlimitedGet-DistributionGroup -ResultSize Unlimited
|
New-DistributionGroupNew-DistributionGroup
|
Verteilergruppe anlegenCreate a distribution group |
New-DistributionGroup -Name "IT Alerts" -PrimarySmtpAddress italerts@contoso.comNew-DistributionGroup -Name "IT Alerts" -PrimarySmtpAddress italerts@contoso.com
|
Set-DistributionGroupSet-DistributionGroup
|
Verteilergruppe ändernModify a distribution group |
Set-DistributionGroup -Identity "IT Alerts" -ManagedBy admin@contoso.comSet-DistributionGroup -Identity "IT Alerts" -ManagedBy admin@contoso.com
|
Get-DistributionGroupMemberGet-DistributionGroupMember
|
Mitglieder auslesenRead members |
Get-DistributionGroupMember -Identity "IT Alerts"Get-DistributionGroupMember -Identity "IT Alerts"
|
Add-DistributionGroupMemberAdd-DistributionGroupMember
|
Mitglieder hinzufügenAdd members |
Add-DistributionGroupMember -Identity "IT Alerts" -Member user@contoso.comAdd-DistributionGroupMember -Identity "IT Alerts" -Member user@contoso.com
|
Get-TransportRuleGet-TransportRule
|
Mailflow-Regeln lesenRead mail flow rules |
Get-TransportRuleGet-TransportRule
|
New-TransportRuleNew-TransportRule
|
Mailflow-Regel anlegenCreate a mail flow rule |
New-TransportRule -Name "Block EXE" -AttachmentExtensionMatchesWords exe -RejectMessageReasonText "Executable blocked"New-TransportRule -Name "Block EXE" -AttachmentExtensionMatchesWords exe -RejectMessageReasonText "Executable blocked"
|
Set-TransportRuleSet-TransportRule
|
Mailflow-Regel ändernModify a mail flow rule |
Set-TransportRule -Identity "Block EXE" -Mode EnforceSet-TransportRule -Identity "Block EXE" -Mode Enforce
|
Get-MessageTraceGet-MessageTrace
|
Nachrichtenfluss suchenSearch message flow |
Get-MessageTrace -StartDate (Get-Date).AddDays(-7) -EndDate (Get-Date)Get-MessageTrace -StartDate (Get-Date).AddDays(-7) -EndDate (Get-Date)
|
Get-MessageTraceDetailGet-MessageTraceDetail
|
Detail zum Trace abrufenGet message trace detail |
Get-MessageTraceDetail -MessageTraceId $trace.MessageTraceId -RecipientAddress $trace.RecipientAddressGet-MessageTraceDetail -MessageTraceId $trace.MessageTraceId -RecipientAddress $trace.RecipientAddress
|
Get-EXOMailboxFolderStatisticsGet-EXOMailboxFolderStatistics
|
Ordnergrößen prüfenCheck folder sizes |
Get-EXOMailboxFolderStatistics -Identity user@contoso.comGet-EXOMailboxFolderStatistics -Identity user@contoso.com
|
Get-MailContactGet-MailContact
|
Mailkontakte abrufenGet mail contacts |
Get-MailContact -ResultSize UnlimitedGet-MailContact -ResultSize Unlimited
|
Get-MailUserGet-MailUser
|
MailUser abrufenGet mail users |
Get-MailUser -ResultSize UnlimitedGet-MailUser -ResultSize Unlimited
|
Get-EXORecipientGet-EXORecipient
|
Empfänger aller Typen lesenRead recipients of all types |
Get-EXORecipient -ResultSize UnlimitedGet-EXORecipient -ResultSize Unlimited
|
Get-SharedMailboxGet-SharedMailbox
|
Freigegebene Postfächer filternFilter shared mailboxes |
Get-EXOMailbox -RecipientTypeDetails SharedMailboxGet-EXOMailbox -RecipientTypeDetails SharedMailbox
|
Get-QuarantineMessageGet-QuarantineMessage
|
Quarantäneobjekte lesenRead quarantine items |
Get-QuarantineMessage -PageSize 100Get-QuarantineMessage -PageSize 100
|
Get-EXOMailboxPermissionGet-EXOMailboxPermission
|
REST-basierte BerechtigungsprüfungREST-based permission audit |
Get-EXOMailboxPermission -Identity shared@contoso.comGet-EXOMailboxPermission -Identity shared@contoso.com
|
SharePoint Online Management ShellSharePoint Online Management Shell
Für tenantweite SharePoint-Administration bleibt das SPO-Modul nützlich. Für moderne Site- und Inhaltsautomatisierung ist häufig PnP.PowerShell flexibler.For tenant-wide SharePoint administration, the SPO module remains useful. For modern site and content automation, PnP.PowerShell is often more flexible.
Connect-SPOService -Url https://contoso-admin.sharepoint.com
Get-SPOSite -Limit All
| CmdletCmdlet | ZweckPurpose | BeispielExample |
|---|---|---|
Get-SPOSiteGet-SPOSite
|
Sitesammlungen lesenRead site collections |
Get-SPOSite -Limit AllGet-SPOSite -Limit All
|
Set-SPOSiteSet-SPOSite
|
Site-Einstellungen ändernUpdate site settings |
Set-SPOSite -Identity $SiteUrl -SharingCapability ExternalUserSharingOnlySet-SPOSite -Identity $SiteUrl -SharingCapability ExternalUserSharingOnly
|
Get-SPOUserGet-SPOUser
|
Benutzer einer Site lesenRead site users |
Get-SPOUser -Site $SiteUrlGet-SPOUser -Site $SiteUrl
|
Set-SPOUserSet-SPOUser
|
Site-Admin setzenSet site admin |
Set-SPOUser -Site $SiteUrl -LoginName admin@contoso.com -IsSiteCollectionAdmin $trueSet-SPOUser -Site $SiteUrl -LoginName admin@contoso.com -IsSiteCollectionAdmin $true
|
Get-SPODeletedSiteGet-SPODeletedSite
|
Gelöschte Sites abrufenGet deleted sites |
Get-SPODeletedSiteGet-SPODeletedSite
|
Restore-SPODeletedSiteRestore-SPODeletedSite
|
Gelöschte Site wiederherstellenRestore deleted site |
Restore-SPODeletedSite -Identity $SiteUrlRestore-SPODeletedSite -Identity $SiteUrl
|
Set-SPOTenantSet-SPOTenant
|
Tenantweite Einstellungen anpassenAdjust tenant-wide settings |
Set-SPOTenant -SharingCapability ExistingExternalUserSharingOnlySet-SPOTenant -SharingCapability ExistingExternalUserSharingOnly
|
Get-SPOExternalUserGet-SPOExternalUser
|
Externe Benutzer lesenRead external users |
Get-SPOExternalUser -SiteUrl $SiteUrlGet-SPOExternalUser -SiteUrl $SiteUrl
|
PnP.PowerShellPnP.PowerShell
PnP.PowerShell ist das vielseitigste Modul für SharePoint Online, Teams-nahe SharePoint-Strukturen und wiederverwendbare Site-Automatisierung. Es unterstützt Interactive Login, Zertifikate, Managed Identity und app-only Ansätze.PnP.PowerShell is the most versatile module for SharePoint Online, Teams-related SharePoint structures, and reusable site automation. It supports interactive login, certificates, managed identity, and app-only approaches.
| AuthentifizierungAuthentication | BeispielExample | Wann sinnvoll?When useful? |
|---|---|---|
| InteraktivInteractive |
Connect-PnPOnline -Url https://contoso.sharepoint.com -InteractiveConnect-PnPOnline -Url https://contoso.sharepoint.com -Interactive
|
Ad-hoc-AdministrationAd-hoc administration |
| ZertifikatCertificate |
Connect-PnPOnline -Url https://contoso.sharepoint.com -ClientId $AppId -Tenant contoso.onmicrosoft.com -Thumbprint $ThumbprintConnect-PnPOnline -Url https://contoso.sharepoint.com -ClientId $AppId -Tenant contoso.onmicrosoft.com -Thumbprint $Thumbprint
|
Runbooks und produktive JobsRunbooks and production jobs |
| Managed IdentityManaged Identity |
Connect-PnPOnline -Url https://contoso.sharepoint.com -ManagedIdentityConnect-PnPOnline -Url https://contoso.sharepoint.com -ManagedIdentity
|
Azure Automation und FunctionsAzure Automation and Functions |
| CmdletCmdlet | ZweckPurpose | BeispielExample |
|---|---|---|
Get-PnPSiteGet-PnPSite
|
Site-Metadaten lesenRead site metadata |
Get-PnPSiteGet-PnPSite
|
Get-PnPWebGet-PnPWeb
|
Webobjekt lesenRead web object |
Get-PnPWebGet-PnPWeb
|
Get-PnPListGet-PnPList
|
Listen abrufenGet lists |
Get-PnPListGet-PnPList
|
Get-PnPListItemGet-PnPListItem
|
Listeneinträge abrufenGet list items |
Get-PnPListItem -List "Documents"Get-PnPListItem -List "Documents"
|
Add-PnPListItemAdd-PnPListItem
|
Listeneintrag erstellenCreate list item |
Add-PnPListItem -List "Assets" -Values @{Title="Laptop-001"}Add-PnPListItem -List "Assets" -Values @{Title="Laptop-001"}
|
Set-PnPListItemSet-PnPListItem
|
Listeneintrag aktualisierenUpdate list item |
Set-PnPListItem -List "Assets" -Identity 1 -Values @{Status="Assigned"}Set-PnPListItem -List "Assets" -Identity 1 -Values @{Status="Assigned"}
|
Get-PnPFolderItemGet-PnPFolderItem
|
Dateien und Ordner lesenRead files and folders |
Get-PnPFolderItem -FolderSiteRelativeUrl "Shared Documents"Get-PnPFolderItem -FolderSiteRelativeUrl "Shared Documents"
|
Get-PnPRecycleBinItemGet-PnPRecycleBinItem
|
Papierkorb prüfenInspect recycle bin |
Get-PnPRecycleBinItemGet-PnPRecycleBinItem
|
Microsoft Teams PowerShellMicrosoft Teams PowerShell
Das MicrosoftTeams-Modul deckt Richtlinien, Teams-Objekte, Kanäle, Telefonie und viele Tenant-Einstellungen ab. In der Praxis wird es oft mit Graph und Exchange kombiniert.The MicrosoftTeams module covers policies, teams objects, channels, telephony, and many tenant settings. In practice, it is often combined with Graph and Exchange.
Connect-MicrosoftTeams
Get-CsTenant
| CmdletCmdlet | ZweckPurpose | BeispielExample |
|---|---|---|
Get-TeamGet-Team
|
Teams lesenRead teams |
Get-TeamGet-Team
|
New-TeamNew-Team
|
Team erstellenCreate a team |
New-Team -DisplayName "Operations" -Visibility PrivateNew-Team -DisplayName "Operations" -Visibility Private
|
Set-TeamSet-Team
|
Team konfigurierenConfigure a team |
Set-Team -GroupId $GroupId -AllowCreateUpdateChannels $falseSet-Team -GroupId $GroupId -AllowCreateUpdateChannels $false
|
Get-TeamChannelGet-TeamChannel
|
Kanäle lesenRead channels |
Get-TeamChannel -GroupId $GroupIdGet-TeamChannel -GroupId $GroupId
|
New-TeamChannelNew-TeamChannel
|
Kanal anlegenCreate a channel |
New-TeamChannel -GroupId $GroupId -DisplayName "Projekt"New-TeamChannel -GroupId $GroupId -DisplayName "Projekt"
|
Get-CsTeamsMessagingPolicyGet-CsTeamsMessagingPolicy
|
Messaging Policies lesenRead messaging policies |
Get-CsTeamsMessagingPolicyGet-CsTeamsMessagingPolicy
|
Get-CsTeamsMeetingPolicyGet-CsTeamsMeetingPolicy
|
Meeting Policies lesenRead meeting policies |
Get-CsTeamsMeetingPolicyGet-CsTeamsMeetingPolicy
|
Grant-CsTeamsMeetingPolicyGrant-CsTeamsMeetingPolicy
|
Meeting Policy zuweisenAssign meeting policy |
Grant-CsTeamsMeetingPolicy -Identity user@contoso.com -PolicyName RestrictedMeetingGrant-CsTeamsMeetingPolicy -Identity user@contoso.com -PolicyName RestrictedMeeting
|
Get-CsOnlineUserGet-CsOnlineUser
|
Voice/Teams-Benutzer prüfenInspect voice/Teams users |
Get-CsOnlineUser -Identity user@contoso.comGet-CsOnlineUser -Identity user@contoso.com
|
Get-CsPhoneNumberAssignmentGet-CsPhoneNumberAssignment
|
Rufnummernzuweisungen lesenRead number assignments |
Get-CsPhoneNumberAssignmentGet-CsPhoneNumberAssignment
|
Komplettes VerbindungsskriptComplete connection script
$tenantId = "contoso.onmicrosoft.com"
$adminUpn = "admin@contoso.com"
$spoAdminUrl = "https://contoso-admin.sharepoint.com"
$siteUrl = "https://contoso.sharepoint.com/sites/Operations"
Import-Module Microsoft.Graph
Import-Module ExchangeOnlineManagement
Import-Module Microsoft.Online.SharePoint.PowerShell
Import-Module PnP.PowerShell
Import-Module MicrosoftTeams
Connect-MgGraph -Scopes "User.Read.All","Group.Read.All","Directory.Read.All","AuditLog.Read.All"
Connect-ExchangeOnline -UserPrincipalName $adminUpn
Connect-SPOService -Url $spoAdminUrl
Connect-PnPOnline -Url $siteUrl -Interactive
Connect-MicrosoftTeams
Write-Host "Graph context:" (Get-MgContext).TenantId
Write-Host "Exchange connected:" ((Get-ConnectionInformation).State -join ", ")
Write-Host "Teams tenant:" (Get-CsTenant).DisplayName
SkriptsammlungScript collection
Alle Benutzer nach CSV exportierenExport all users to CSV
Dieses Skript ist als sofort nutzbare Vorlage gedacht und kann direkt in eine Admin-Shell oder in ein Runbook übernommen werden.This script is intended as an immediately usable template and can be copied into an admin shell or runbook.
$properties = @(
"id","displayName","givenName","surname","userPrincipalName","mail",
"department","jobTitle","officeLocation","accountEnabled","usageLocation",
"city","country","mobilePhone","businessPhones","onPremisesSyncEnabled"
)
Connect-MgGraph -Scopes "User.Read.All"
$users = Get-MgUser -All -Property $properties
$report = foreach ($user in $users) {
[pscustomobject]@{
Id = $user.Id
DisplayName = $user.DisplayName
GivenName = $user.GivenName
Surname = $user.Surname
UserPrincipalName = $user.UserPrincipalName
Mail = $user.Mail
Department = $user.Department
JobTitle = $user.JobTitle
OfficeLocation = $user.OfficeLocation
AccountEnabled = $user.AccountEnabled
UsageLocation = $user.UsageLocation
City = $user.City
Country = $user.Country
MobilePhone = $user.MobilePhone
OnPremisesSyncEnabled= $user.OnPremisesSyncEnabled
}
}
$report | Export-Csv .\all-users.csv -NoTypeInformation -Encoding UTF8
Inaktive Benutzer 90+ Tage findenFind inactive users for 90+ days
Dieses Skript ist als sofort nutzbare Vorlage gedacht und kann direkt in eine Admin-Shell oder in ein Runbook übernommen werden.This script is intended as an immediately usable template and can be copied into an admin shell or runbook.
Connect-MgGraph -Scopes "User.Read.All","AuditLog.Read.All"
Select-MgProfile -Name beta
$cutoff = (Get-Date).AddDays(-90)
$users = Get-MgUser -All -Property "displayName,userPrincipalName,accountEnabled,signInActivity"
$inactive = foreach ($user in $users) {
$last = $null
if ($user.SignInActivity.lastSignInDateTime) {
$last = [datetime]$user.SignInActivity.lastSignInDateTime
}
if (-not $last -or $last -lt $cutoff) {
[pscustomobject]@{
DisplayName = $user.DisplayName
UserPrincipalName = $user.UserPrincipalName
AccountEnabled = $user.AccountEnabled
LastSignIn = $last
DaysInactive = if ($last) { ((Get-Date) - $last).Days } else { $null }
}
}
}
$inactive | Sort-Object DaysInactive -Descending | Export-Csv .\inactive-users.csv -NoTypeInformation
Benutzer aus CSV massenhaft anlegenBulk create users from CSV
Dieses Skript ist als sofort nutzbare Vorlage gedacht und kann direkt in eine Admin-Shell oder in ein Runbook übernommen werden.This script is intended as an immediately usable template and can be copied into an admin shell or runbook.
Connect-MgGraph -Scopes "User.ReadWrite.All"
$users = Import-Csv .\new-users.csv
foreach ($row in $users) {
$passwordProfile = @{
forceChangePasswordNextSignIn = $true
password = $row.InitialPassword
}
New-MgUser -AccountEnabled:$true `
-DisplayName $row.DisplayName `
-GivenName $row.GivenName `
-Surname $row.Surname `
-MailNickname $row.MailNickname `
-UserPrincipalName $row.UserPrincipalName `
-Department $row.Department `
-JobTitle $row.JobTitle `
-UsageLocation $row.UsageLocation `
-PasswordProfile $passwordProfile
Write-Host "Created $($row.UserPrincipalName)"
}
Alle Gruppen und Mitglieder exportierenExport all groups and members
Dieses Skript ist als sofort nutzbare Vorlage gedacht und kann direkt in eine Admin-Shell oder in ein Runbook übernommen werden.This script is intended as an immediately usable template and can be copied into an admin shell or runbook.
Connect-MgGraph -Scopes "Group.Read.All","GroupMember.Read.All"
$groups = Get-MgGroup -All -Property "id,displayName,groupTypes,mail,mailEnabled,securityEnabled"
$rows = foreach ($group in $groups) {
$members = Get-MgGroupMember -GroupId $group.Id -All
foreach ($member in $members) {
[pscustomobject]@{
GroupId = $group.Id
GroupDisplayName = $group.DisplayName
GroupMail = $group.Mail
SecurityEnabled = $group.SecurityEnabled
MailEnabled = $group.MailEnabled
MemberId = $member.Id
MemberType = $member.AdditionalProperties['@odata.type']
}
}
}
$rows | Export-Csv .\groups-and-members.csv -NoTypeInformation -Encoding UTF8
Lizenzzuweisungsbericht erzeugenCreate license assignment report
Dieses Skript ist als sofort nutzbare Vorlage gedacht und kann direkt in eine Admin-Shell oder in ein Runbook übernommen werden.This script is intended as an immediately usable template and can be copied into an admin shell or runbook.
Connect-MgGraph -Scopes "User.Read.All","Organization.Read.All"
$skuMap = @{}
Get-MgSubscribedSku -All | ForEach-Object {
$skuMap[$_.SkuId.Guid] = $_.SkuPartNumber
}
$users = Get-MgUser -All -Property "displayName,userPrincipalName,assignedLicenses,usageLocation"
$report = foreach ($user in $users) {
[pscustomobject]@{
DisplayName = $user.DisplayName
UserPrincipalName = $user.UserPrincipalName
UsageLocation = $user.UsageLocation
Licenses = ($user.AssignedLicenses.SkuId.Guid | ForEach-Object { $skuMap[$_] }) -join '; '
LicenseCount = $user.AssignedLicenses.Count
}
}
$report | Export-Csv .\license-assignment-report.csv -NoTypeInformation
MFA-Registrierungsstatus berichtenReport MFA registration status
Dieses Skript ist als sofort nutzbare Vorlage gedacht und kann direkt in eine Admin-Shell oder in ein Runbook übernommen werden.This script is intended as an immediately usable template and can be copied into an admin shell or runbook.
Connect-MgGraph -Scopes "Reports.Read.All"
$rows = Get-MgReportAuthenticationMethodUserRegistrationDetail -All
$report = $rows | Select-Object `
UserPrincipalName,
UserDisplayName,
IsMfaRegistered,
IsSsprRegistered,
IsPasswordlessCapable,
IsAdmin,
DefaultMfaMethod,
MethodsRegistered
$report | Export-Csv .\mfa-registration-status.csv -NoTypeInformation -Encoding UTF8
Conditional-Access-Richtlinien nach JSON exportierenExport conditional access policies to JSON
Dieses Skript ist als sofort nutzbare Vorlage gedacht und kann direkt in eine Admin-Shell oder in ein Runbook übernommen werden.This script is intended as an immediately usable template and can be copied into an admin shell or runbook.
Connect-MgGraph -Scopes "Policy.Read.All"
$policies = Get-MgIdentityConditionalAccessPolicy -All
$export = foreach ($policy in $policies) {
[pscustomobject]@{
Id = $policy.Id
DisplayName = $policy.DisplayName
State = $policy.State
Conditions = $policy.Conditions
GrantControls = $policy.GrantControls
SessionControls = $policy.SessionControls
}
}
$export | ConvertTo-Json -Depth 20 | Set-Content .\conditional-access-policies.json -Encoding UTF8
Postfachberechtigungen auditierenAudit mailbox permissions
Dieses Skript ist als sofort nutzbare Vorlage gedacht und kann direkt in eine Admin-Shell oder in ein Runbook übernommen werden.This script is intended as an immediately usable template and can be copied into an admin shell or runbook.
Connect-ExchangeOnline -UserPrincipalName admin@contoso.com
$mailboxes = Get-EXOMailbox -ResultSize Unlimited
$report = foreach ($mailbox in $mailboxes) {
$permissions = Get-MailboxPermission -Identity $mailbox.UserPrincipalName |
Where-Object { $_.User -notlike 'NT AUTHORITY*' -and -not $_.IsInherited }
foreach ($permission in $permissions) {
[pscustomobject]@{
Mailbox = $mailbox.UserPrincipalName
Trustee = $permission.User
AccessRights= ($permission.AccessRights -join ', ')
Deny = $permission.Deny
}
}
}
$report | Export-Csv .\mailbox-permissions.csv -NoTypeInformation -Encoding UTF8
Freigegebene Postfächer vollständig berichtenCreate shared mailbox full report
Dieses Skript ist als sofort nutzbare Vorlage gedacht und kann direkt in eine Admin-Shell oder in ein Runbook übernommen werden.This script is intended as an immediately usable template and can be copied into an admin shell or runbook.
Connect-ExchangeOnline -UserPrincipalName admin@contoso.com
$sharedMailboxes = Get-EXOMailbox -RecipientTypeDetails SharedMailbox -ResultSize Unlimited
$report = foreach ($mailbox in $sharedMailboxes) {
$stats = Get-EXOMailboxStatistics -Identity $mailbox.UserPrincipalName
[pscustomobject]@{
DisplayName = $mailbox.DisplayName
PrimarySmtpAddress = $mailbox.PrimarySmtpAddress
HiddenFromAddressList= $mailbox.HiddenFromAddressListsEnabled
LitigationHold = $mailbox.LitigationHoldEnabled
ArchiveStatus = $mailbox.ArchiveStatus
ItemCount = $stats.ItemCount
TotalItemSize = $stats.TotalItemSize
LastLogonTime = $stats.LastLogonTime
}
}
$report | Export-Csv .\shared-mailbox-report.csv -NoTypeInformation -Encoding UTF8
Gastbenutzer mit letzter Anmeldung berichtenReport guest users with last sign-in
Dieses Skript ist als sofort nutzbare Vorlage gedacht und kann direkt in eine Admin-Shell oder in ein Runbook übernommen werden.This script is intended as an immediately usable template and can be copied into an admin shell or runbook.
Connect-MgGraph -Scopes "User.Read.All","AuditLog.Read.All"
Select-MgProfile -Name beta
$guests = Get-MgUser -All -Filter "userType eq 'Guest'" -Property "displayName,userPrincipalName,mail,createdDateTime,signInActivity"
$report = foreach ($guest in $guests) {
[pscustomobject]@{
DisplayName = $guest.DisplayName
UserPrincipalName = $guest.UserPrincipalName
Mail = $guest.Mail
CreatedDateTime = $guest.CreatedDateTime
LastSignIn = $guest.SignInActivity.lastSignInDateTime
}
}
$report | Export-Csv .\guest-users-last-signin.csv -NoTypeInformation -Encoding UTF8
Veraltete Geräte bereinigenClean up stale devices
Dieses Skript ist als sofort nutzbare Vorlage gedacht und kann direkt in eine Admin-Shell oder in ein Runbook übernommen werden.This script is intended as an immediately usable template and can be copied into an admin shell or runbook.
Connect-MgGraph -Scopes "Device.ReadWrite.All","DeviceManagementManagedDevices.Read.All"
$cutoff = (Get-Date).AddDays(-120)
$devices = Get-MgDevice -All -Property "id,displayName,approximateLastSignInDateTime,accountEnabled"
$stale = $devices | Where-Object {
$_.ApproximateLastSignInDateTime -and ([datetime]$_.ApproximateLastSignInDateTime) -lt $cutoff
}
$stale | Select-Object Id, DisplayName, ApproximateLastSignInDateTime, AccountEnabled |
Export-Csv .\stale-devices.csv -NoTypeInformation
# Review CSV first, then uncomment the next line for cleanup
# $stale | ForEach-Object { Update-MgDevice -DeviceId $_.Id -AccountEnabled:$false }
Lizenzen aus CSV massenhaft zuweisenBulk assign licenses from CSV
Dieses Skript ist als sofort nutzbare Vorlage gedacht und kann direkt in eine Admin-Shell oder in ein Runbook übernommen werden.This script is intended as an immediately usable template and can be copied into an admin shell or runbook.
Connect-MgGraph -Scopes "User.ReadWrite.All","Organization.Read.All"
$skuMap = Get-MgSubscribedSku -All | Group-Object SkuPartNumber -AsHashTable -AsString
$rows = Import-Csv .\license-assignments.csv
foreach ($row in $rows) {
$sku = $skuMap[$row.SkuPartNumber]
if (-not $sku) {
Write-Warning "SKU $($row.SkuPartNumber) not found"
continue
}
$body = @{
addLicenses = @(@{ skuId = $sku.SkuId })
removeLicenses = @()
}
Set-MgUserLicense -UserId $row.UserPrincipalName -BodyParameter $body
Write-Host "Assigned $($row.SkuPartNumber) to $($row.UserPrincipalName)"
}
Sicherheitsgruppen-Mitgliedschaften vergleichenCompare security group memberships
Dieses Skript ist als sofort nutzbare Vorlage gedacht und kann direkt in eine Admin-Shell oder in ein Runbook übernommen werden.This script is intended as an immediately usable template and can be copied into an admin shell or runbook.
$groupAId = "11111111-1111-1111-1111-111111111111"
$groupBId = "22222222-2222-2222-2222-222222222222"
Connect-MgGraph -Scopes "GroupMember.Read.All"
$groupA = Get-MgGroupMember -GroupId $groupAId -All | Select-Object -ExpandProperty Id
$groupB = Get-MgGroupMember -GroupId $groupBId -All | Select-Object -ExpandProperty Id
$onlyA = $groupA | Where-Object { $_ -notin $groupB }
$onlyB = $groupB | Where-Object { $_ -notin $groupA }
[pscustomobject]@{ Comparison = "OnlyInA"; Count = $onlyA.Count }
[pscustomobject]@{ Comparison = "OnlyInB"; Count = $onlyB.Count }
$onlyA | Set-Content .\group-a-only.txt
$onlyB | Set-Content .\group-b-only.txt
App-Registrierungen mit Secret-Ablauf berichtenReport app registration secret expiry
Dieses Skript ist als sofort nutzbare Vorlage gedacht und kann direkt in eine Admin-Shell oder in ein Runbook übernommen werden.This script is intended as an immediately usable template and can be copied into an admin shell or runbook.
Connect-MgGraph -Scopes "Application.Read.All"
$applications = Get-MgApplication -All -Property "id,displayName,passwordCredentials,keyCredentials"
$today = Get-Date
$report = foreach ($app in $applications) {
foreach ($secret in $app.PasswordCredentials) {
[pscustomobject]@{
AppDisplayName = $app.DisplayName
AppId = $app.Id
CredentialType = "ClientSecret"
EndDateTime = $secret.EndDateTime
DaysRemaining = ([datetime]$secret.EndDateTime - $today).Days
}
}
}
$report | Sort-Object DaysRemaining | Export-Csv .\app-secret-expiry.csv -NoTypeInformation
Benutzer-Anmeldeaktivitäten berichtenReport user sign-in activity
Dieses Skript ist als sofort nutzbare Vorlage gedacht und kann direkt in eine Admin-Shell oder in ein Runbook übernommen werden.This script is intended as an immediately usable template and can be copied into an admin shell or runbook.
Connect-MgGraph -Scopes "AuditLog.Read.All","User.Read.All"
$since = (Get-Date).AddDays(-30)
$signIns = Get-MgAuditLogSignIn -All -Filter "createdDateTime ge $($since.ToString("s"))Z"
$report = $signIns | Group-Object UserPrincipalName | ForEach-Object {
$latest = $_.Group | Sort-Object CreatedDateTime -Descending | Select-Object -First 1
[pscustomobject]@{
UserPrincipalName = $_.Name
SignInCount = $_.Count
LastSignIn = $latest.CreatedDateTime
LastApp = $latest.AppDisplayName
LastIpAddress = $latest.IpAddress
LastStatus = $latest.Status.ErrorCode
}
}
$report | Export-Csv .\user-signin-activity.csv -NoTypeInformation -Encoding UTF8
20 More Complete Scripts20 More Complete Scripts
Die folgenden Skripte sind als produktionsnahe Vorlagen gedacht: mit Fehlerbehandlung, kommentierten Schritten und CSV-/JSON-Export. Passe Tenant-spezifische Scope-Sets, Delays und Ausgabeorte an deine Betriebsrichtlinien an.The following scripts are designed as production-oriented templates with error handling, commented steps, and CSV/JSON export. Adjust tenant-specific scope sets, delays, and output paths to match your operational standards.
Viele Skripte kombinieren Microsoft Graph, Exchange Online, Teams oder SharePoint. In produktiven Runbooks sollten Modulversionen fixiert, Ausgaben zentral protokolliert und Secrets ausschließlich über verwaltete Identitäten oder sichere Secret Stores bezogen werden.Many scripts combine Microsoft Graph, Exchange Online, Teams, or SharePoint. In production runbooks, pin module versions, centralize logging, and obtain secrets only from managed identities or secure secret stores.
Conditional Access Policy BackupConditional Access Policy Backup
Exportiert alle Conditional-Access-Richtlinien als einzelne JSON-Dateien plus Inventar-CSV.Exports all Conditional Access policies as individual JSON files plus an inventory CSV.
- Microsoft.Graph.Identity.SignInsMicrosoft.Graph.Identity.SignIns
- Scopes: Policy.Read.AllScopes: Policy.Read.All
- Ausführbar auf jedem Admin-ClientRuns on any admin workstation
param(
[string]$OutputFolder = ".\ca-policy-backup"
)
try {
# Load module and connect to Microsoft Graph
Import-Module Microsoft.Graph.Identity.SignIns -ErrorAction Stop
Connect-MgGraph -Scopes "Policy.Read.All" -NoWelcome -ErrorAction Stop
if (-not (Test-Path $OutputFolder)) {
New-Item -Path $OutputFolder -ItemType Directory -Force | Out-Null
}
$policies = Get-MgIdentityConditionalAccessPolicy -All -ErrorAction Stop
$inventory = foreach ($policy in $policies) {
$safeName = ($policy.DisplayName -replace '[^a-zA-Z0-9-_ ]','_').Trim()
$jsonPath = Join-Path $OutputFolder "$safeName.json"
# Persist full object for restore or diff scenarios
$policy | ConvertTo-Json -Depth 25 | Set-Content -Path $jsonPath -Encoding UTF8
[pscustomobject]@{
DisplayName = $policy.DisplayName
Id = $policy.Id
State = $policy.State
OutputFile = $jsonPath
}
}
$inventory | Export-Csv (Join-Path $OutputFolder 'ca-policy-inventory.csv') -NoTypeInformation -Encoding UTF8
}
catch {
Write-Error "Conditional Access backup failed: $($_.Exception.Message)"
throw
}
finally {
Disconnect-MgGraph -ErrorAction SilentlyContinue | Out-Null
}
Stale Guest User CleanupStale Guest User Cleanup
Findet Gastkonten ohne Anmeldung in den letzten 180 Tagen, exportiert sie und entfernt sie optional.Finds guest accounts with no sign-in during the last 180 days, exports them, and optionally removes them.
- Microsoft.Graph.Users + Microsoft.Graph.Identity.SignInsMicrosoft.Graph.Users + Microsoft.Graph.Identity.SignIns
- Scopes: User.Read.All, AuditLog.Read.All, User.ReadWrite.AllScopes: User.Read.All, AuditLog.Read.All, User.ReadWrite.All
- Für Löschung Admin-Rolle notwendigAdmin role required for deletion
param(
[int]$InactiveDays = 180,
[switch]$RemoveAccounts,
[string]$OutputPath = ".\stale-guest-users.csv"
)
try {
# Connect and load all guest users with sign-in activity
Import-Module Microsoft.Graph.Users, Microsoft.Graph.Identity.SignIns -ErrorAction Stop
Connect-MgGraph -Scopes "User.Read.All","AuditLog.Read.All","User.ReadWrite.All" -NoWelcome -ErrorAction Stop
$cutoff = (Get-Date).AddDays(-$InactiveDays)
$guests = Get-MgUser -All -Filter "userType eq 'Guest'" -Property Id,DisplayName,UserPrincipalName,CreatedDateTime,SignInActivity
$staleGuests = $guests | Where-Object {
-not $_.SignInActivity.LastSignInDateTime -or ([datetime]$_.SignInActivity.LastSignInDateTime) -lt $cutoff
} | Select-Object DisplayName, UserPrincipalName, CreatedDateTime,
@{Name='LastSignInDateTime';Expression={$_.SignInActivity.LastSignInDateTime}},
@{Name='DaysInactive';Expression={ if ($_.SignInActivity.LastSignInDateTime) { ((Get-Date) - [datetime]$_.SignInActivity.LastSignInDateTime).Days } else { 9999 } }}
$staleGuests | Export-Csv $OutputPath -NoTypeInformation -Encoding UTF8
if ($RemoveAccounts) {
foreach ($guest in $staleGuests) {
# Remove only after review and explicit switch usage
Remove-MgUser -UserId $guest.UserPrincipalName -ErrorAction Stop
}
}
}
catch {
Write-Error "Guest cleanup failed: $($_.Exception.Message)"
throw
}
finally {
Disconnect-MgGraph -ErrorAction SilentlyContinue | Out-Null
}
App Registration Secret Expiry ReportApp Registration Secret Expiry Report
Meldet alle App-Registrierungen mit Secrets, die in 30, 60 oder 90 Tagen ablaufen.Reports all app registrations with secrets expiring in 30, 60, or 90 days.
- Microsoft.Graph.ApplicationsMicrosoft.Graph.Applications
- Scopes: Application.Read.AllScopes: Application.Read.All
- CSV-ExportCSV export
param(
[int[]]$ThresholdDays = @(30,60,90),
[string]$OutputPath = ".\app-secret-expiry-report.csv"
)
try {
# Load applications and inspect password credentials
Import-Module Microsoft.Graph.Applications -ErrorAction Stop
Connect-MgGraph -Scopes "Application.Read.All" -NoWelcome -ErrorAction Stop
$today = Get-Date
$maxThreshold = ($ThresholdDays | Measure-Object -Maximum).Maximum
$applications = Get-MgApplication -All -Property Id,DisplayName,AppId,PasswordCredentials
$report = foreach ($app in $applications) {
foreach ($secret in $app.PasswordCredentials) {
$daysRemaining = ([datetime]$secret.EndDateTime - $today).Days
if ($daysRemaining -le $maxThreshold) {
[pscustomobject]@{
DisplayName = $app.DisplayName
ApplicationId = $app.AppId
ObjectId = $app.Id
SecretName = $secret.DisplayName
EndDateTime = $secret.EndDateTime
DaysRemaining = $daysRemaining
Bucket = ($ThresholdDays | Where-Object { $daysRemaining -le $_ } | Sort-Object | Select-Object -First 1)
}
}
}
}
$report | Sort-Object DaysRemaining | Export-Csv $OutputPath -NoTypeInformation -Encoding UTF8
}
catch {
Write-Error "Secret expiry report failed: $($_.Exception.Message)"
throw
}
finally {
Disconnect-MgGraph -ErrorAction SilentlyContinue | Out-Null
}
Group Membership Delta ReportGroup Membership Delta Report
Vergleicht zwei exportierte Gruppensnapshots und zeigt neue sowie entfernte Mitglieder.Compares two exported group snapshots and shows newly added and removed members.
- Zwei CSV-Snapshots mit GroupId, GroupName, MemberUPNTwo CSV snapshots with GroupId, GroupName, MemberUPN
- Kein Cloud-Zugriff nötigNo cloud access required
- Ideal für geplante Snapshot-JobsIdeal for scheduled snapshot jobs
param(
[Parameter(Mandatory)]
[string]$BeforeSnapshot,
[Parameter(Mandatory)]
[string]$AfterSnapshot,
[string]$OutputPath = ".\group-membership-delta.csv"
)
try {
# Import two snapshots and compare member state per group
$before = Import-Csv $BeforeSnapshot -ErrorAction Stop
$after = Import-Csv $AfterSnapshot -ErrorAction Stop
$delta = foreach ($groupId in ($after.GroupId + $before.GroupId | Sort-Object -Unique)) {
$beforeMembers = $before | Where-Object GroupId -eq $groupId | Select-Object -ExpandProperty MemberUPN
$afterMembers = $after | Where-Object GroupId -eq $groupId | Select-Object -ExpandProperty MemberUPN
$groupName = ($after | Where-Object GroupId -eq $groupId | Select-Object -ExpandProperty GroupName -First 1)
if (-not $groupName) {
$groupName = ($before | Where-Object GroupId -eq $groupId | Select-Object -ExpandProperty GroupName -First 1)
}
Compare-Object -ReferenceObject $beforeMembers -DifferenceObject $afterMembers -PassThru | ForEach-Object {
[pscustomobject]@{
GroupId = $groupId
GroupName = $groupName
MemberUPN = $_
ChangeType = if ($_.SideIndicator -eq '=>') { 'Added' } else { 'Removed' }
}
}
}
$delta | Sort-Object GroupName, ChangeType, MemberUPN | Export-Csv $OutputPath -NoTypeInformation -Encoding UTF8
}
catch {
Write-Error "Group delta report failed: $($_.Exception.Message)"
throw
}
Mailbox Size ReportMailbox Size Report
Erstellt einen Exchange-Report mit Mailboxgröße, Elementanzahl und letzter Aktivität.Builds an Exchange report with mailbox size, item count, and last activity.
- ExchangeOnlineManagementExchangeOnlineManagement
- Exchange Administrator oder passende delegierte RechteExchange Administrator or equivalent delegated rights
- Get-EXOMailbox + Get-EXOMailboxStatisticsGet-EXOMailbox + Get-EXOMailboxStatistics
param(
[string]$OutputPath = ".\mailbox-size-report.csv"
)
try {
# Connect to Exchange Online and enumerate user mailboxes
Import-Module ExchangeOnlineManagement -ErrorAction Stop
Connect-ExchangeOnline -ShowBanner:$false -ErrorAction Stop
$mailboxes = Get-EXOMailbox -ResultSize Unlimited -RecipientTypeDetails UserMailbox
$report = foreach ($mailbox in $mailboxes) {
$stats = Get-EXOMailboxStatistics -Identity $mailbox.UserPrincipalName -ErrorAction Stop
[pscustomobject]@{
DisplayName = $mailbox.DisplayName
UserPrincipalName = $mailbox.UserPrincipalName
PrimarySmtpAddress = $mailbox.PrimarySmtpAddress
TotalItemSize = $stats.TotalItemSize
ItemCount = $stats.ItemCount
LastLogonTime = $stats.LastLogonTime
LastUserActionTime = $stats.LastUserActionTime
}
}
$report | Export-Csv $OutputPath -NoTypeInformation -Encoding UTF8
}
catch {
Write-Error "Mailbox size report failed: $($_.Exception.Message)"
throw
}
finally {
Disconnect-ExchangeOnline -Confirm:$false -ErrorAction SilentlyContinue
}
Teams Ownership ReportTeams Ownership Report
Ermittelt Besitzeranzahl, Mitgliederanzahl und letzte Aktivität für alle Teams.Calculates owner count, member count, and last activity for all teams.
- MicrosoftTeamsMicrosoftTeams
- Teams AdministratorTeams Administrator
- Get-Team + Get-TeamUserGet-Team + Get-TeamUser
param(
[string]$OutputPath = ".\teams-ownership-report.csv"
)
try {
# Connect to Teams and inspect owner/member ratios
Import-Module MicrosoftTeams -ErrorAction Stop
Connect-MicrosoftTeams -ErrorAction Stop
$teams = Get-Team
$report = foreach ($team in $teams) {
$users = Get-TeamUser -GroupId $team.GroupId
[pscustomobject]@{
DisplayName = $team.DisplayName
GroupId = $team.GroupId
OwnerCount = ($users | Where-Object Role -eq 'Owner').Count
MemberCount = ($users | Where-Object Role -eq 'Member').Count
Visibility = $team.Visibility
Archived = $team.Archived
LastActivity = $team.LastActivityDate
}
}
$report | Sort-Object OwnerCount, MemberCount -Descending | Export-Csv $OutputPath -NoTypeInformation -Encoding UTF8
}
catch {
Write-Error "Teams ownership report failed: $($_.Exception.Message)"
throw
}
SharePoint Storage ReportSharePoint Storage Report
Exportiert alle SharePoint-Sites mit belegtem und zugewiesenem Speicher.Exports all SharePoint sites with used and allocated storage.
- Microsoft.Online.SharePoint.PowerShellMicrosoft.Online.SharePoint.PowerShell
- SharePoint AdministratorSharePoint Administrator
- Tenant Admin URLTenant admin URL
param(
[Parameter(Mandatory)]
[string]$AdminUrl,
[string]$OutputPath = ".\sharepoint-storage-report.csv"
)
try {
# Connect to SharePoint Online admin service
Import-Module Microsoft.Online.SharePoint.PowerShell -ErrorAction Stop
Connect-SPOService -Url $AdminUrl -ErrorAction Stop
$sites = Get-SPOSite -Limit All -Detailed
$report = $sites | Select-Object Url, Title, Owner,
@{Name='StorageMB';Expression={$_.StorageUsageCurrent}},
@{Name='StorageQuotaMB';Expression={$_.StorageQuota}},
@{Name='Template';Expression={$_.Template}},
@{Name='LastContentModifiedDate';Expression={$_.LastContentModifiedDate}}
$report | Sort-Object StorageMB -Descending | Export-Csv $OutputPath -NoTypeInformation -Encoding UTF8
}
catch {
Write-Error "SharePoint storage report failed: $($_.Exception.Message)"
throw
}
Conditional Access Gap AnalysisConditional Access Gap Analysis
Markiert aktive Benutzer, die von keiner produktiven CA-Richtlinie explizit erfasst werden.Flags active users not explicitly covered by any production Conditional Access policy.
- Microsoft.Graph.Users + Microsoft.Graph.Groups + Microsoft.Graph.Identity.SignInsMicrosoft.Graph.Users + Microsoft.Graph.Groups + Microsoft.Graph.Identity.SignIns
- Scopes: User.Read.All, Group.Read.All, Policy.Read.AllScopes: User.Read.All, Group.Read.All, Policy.Read.All
- Heuristik für direkte Benutzer-/GruppenzuweisungenHeuristic for direct user/group assignments
param(
[string]$OutputPath = ".\conditional-access-gap-analysis.csv"
)
try {
# Load active member users and enabled CA policies
Import-Module Microsoft.Graph.Users, Microsoft.Graph.Groups, Microsoft.Graph.Identity.SignIns -ErrorAction Stop
Connect-MgGraph -Scopes "User.Read.All","Group.Read.All","Policy.Read.All" -NoWelcome -ErrorAction Stop
$users = Get-MgUser -All -Filter "accountEnabled eq true and userType eq 'Member'" -Property Id,DisplayName,UserPrincipalName
$policies = Get-MgIdentityConditionalAccessPolicy -All | Where-Object State -ne 'disabled'
$coveredUserIds = New-Object System.Collections.Generic.HashSet[string]
foreach ($policy in $policies) {
foreach ($userId in $policy.Conditions.Users.IncludeUsers) { [void]$coveredUserIds.Add($userId) }
foreach ($groupId in $policy.Conditions.Users.IncludeGroups) {
Get-MgGroupMember -GroupId $groupId -All | ForEach-Object { [void]$coveredUserIds.Add($_.Id) }
}
}
$gaps = $users | Where-Object { -not $coveredUserIds.Contains($_.Id) } | Select-Object DisplayName, UserPrincipalName, Id
$gaps | Export-Csv $OutputPath -NoTypeInformation -Encoding UTF8
}
catch {
Write-Error "Conditional Access gap analysis failed: $($_.Exception.Message)"
throw
}
finally {
Disconnect-MgGraph -ErrorAction SilentlyContinue | Out-Null
}
License Reclamation ScriptLicense Reclamation Script
Findet lizenzierte, aber seit 90+ Tagen inaktive Benutzer für Rückgewinnungskampagnen.Finds licensed but inactive users for 90+ day reclamation campaigns.
- Microsoft.Graph.UsersMicrosoft.Graph.Users
- Scopes: User.Read.All, Reports.Read.AllScopes: User.Read.All, Reports.Read.All
- CSV-Export als EntscheidungsgrundlageCSV export for decision making
param(
[int]$InactiveDays = 90,
[string]$OutputPath = ".\license-reclamation-report.csv"
)
try {
# Load user sign-in activity and assigned licenses
Import-Module Microsoft.Graph.Users -ErrorAction Stop
Connect-MgGraph -Scopes "User.Read.All","Reports.Read.All" -NoWelcome -ErrorAction Stop
$cutoff = (Get-Date).AddDays(-$InactiveDays)
$users = Get-MgUser -All -Property Id,DisplayName,UserPrincipalName,AssignedLicenses,SignInActivity,AccountEnabled
$report = $users | Where-Object {
$_.AccountEnabled -and $_.AssignedLicenses.Count -gt 0 -and (
-not $_.SignInActivity.LastSuccessfulSignInDateTime -or
([datetime]$_.SignInActivity.LastSuccessfulSignInDateTime) -lt $cutoff
)
} | Select-Object DisplayName, UserPrincipalName,
@{Name='LicenseCount';Expression={$_.AssignedLicenses.Count}},
@{Name='LastSuccessfulSignIn';Expression={$_.SignInActivity.LastSuccessfulSignInDateTime}},
@{Name='DaysInactive';Expression={ if ($_.SignInActivity.LastSuccessfulSignInDateTime) { ((Get-Date) - [datetime]$_.SignInActivity.LastSuccessfulSignInDateTime).Days } else { 9999 } }}
$report | Sort-Object DaysInactive -Descending | Export-Csv $OutputPath -NoTypeInformation -Encoding UTF8
}
catch {
Write-Error "License reclamation report failed: $($_.Exception.Message)"
throw
}
finally {
Disconnect-MgGraph -ErrorAction SilentlyContinue | Out-Null
}
Privileged Role Assignment ReportPrivileged Role Assignment Report
Listet permanente und eligible Admin-Rollenzuweisungen aus Entra ID und PIM.Lists permanent and eligible admin role assignments from Entra ID and PIM.
- Microsoft.Graph.Identity.GovernanceMicrosoft.Graph.Identity.Governance
- Scopes: RoleManagement.Read.All, Directory.Read.AllScopes: RoleManagement.Read.All, Directory.Read.All
- PIM-Lizenz für eligible AssignmentsPIM license for eligible assignments
param(
[string]$OutputPath = ".\privileged-role-assignments.csv"
)
try {
# Read active and eligible directory role assignments
Import-Module Microsoft.Graph.Identity.Governance -ErrorAction Stop
Connect-MgGraph -Scopes "RoleManagement.Read.All","Directory.Read.All" -NoWelcome -ErrorAction Stop
$activeAssignments = Get-MgRoleManagementDirectoryRoleAssignmentSchedule -All
$eligibleAssignments = Get-MgRoleManagementDirectoryRoleEligibilitySchedule -All
$report = @()
foreach ($assignment in $activeAssignments) {
$report += [pscustomobject]@{
PrincipalId = $assignment.PrincipalId
RoleDefinitionId = $assignment.RoleDefinitionId
AssignmentType = 'Active'
StartDateTime = $assignment.StartDateTime
EndDateTime = $assignment.EndDateTime
}
}
foreach ($assignment in $eligibleAssignments) {
$report += [pscustomobject]@{
PrincipalId = $assignment.PrincipalId
RoleDefinitionId = $assignment.RoleDefinitionId
AssignmentType = 'Eligible'
StartDateTime = $assignment.StartDateTime
EndDateTime = $assignment.EndDateTime
}
}
$report | Export-Csv $OutputPath -NoTypeInformation -Encoding UTF8
}
catch {
Write-Error "Privileged role report failed: $($_.Exception.Message)"
throw
}
finally {
Disconnect-MgGraph -ErrorAction SilentlyContinue | Out-Null
}
External Sharing ReportExternal Sharing Report
Exportiert externe Sharing-Ereignisse für SharePoint und OneDrive aus dem Unified Audit Log.Exports external sharing events for SharePoint and OneDrive from the unified audit log.
- ExchangeOnlineManagementExchangeOnlineManagement
- Audit Logging aktiviertAudit logging enabled
- Compliance Search/Audit BerechtigungCompliance Search/Audit permissions
param(
[int]$Days = 30,
[string]$OutputPath = ".\external-sharing-report.csv"
)
try {
# Search unified audit log for SharePoint and OneDrive sharing events
Import-Module ExchangeOnlineManagement -ErrorAction Stop
Connect-ExchangeOnline -ShowBanner:$false -ErrorAction Stop
$startDate = (Get-Date).AddDays(-$Days)
$operations = 'SharingInvitationCreated','SharingSet','AnonymousLinkCreated','SecureLinkCreated'
$events = Search-UnifiedAuditLog -StartDate $startDate -EndDate (Get-Date) -Operations $operations -ResultSize 5000
$report = $events | ForEach-Object {
$data = $_.AuditData | ConvertFrom-Json
[pscustomobject]@{
CreationDate = $_.CreationDate
Operation = $_.Operations
UserId = $_.UserIds
SiteUrl = $data.SiteUrl
ObjectId = $data.ObjectId
TargetUser = $data.TargetUserOrGroupName
}
}
$report | Export-Csv $OutputPath -NoTypeInformation -Encoding UTF8
}
catch {
Write-Error "External sharing report failed: $($_.Exception.Message)"
throw
}
finally {
Disconnect-ExchangeOnline -Confirm:$false -ErrorAction SilentlyContinue
}
MFA Coverage ReportMFA Coverage Report
Berichtet MFA-Abdeckung und registrierte Methoden pro Benutzer.Reports MFA coverage and registered methods per user.
- Microsoft.Graph.ReportsMicrosoft.Graph.Reports
- Scopes: Reports.Read.All, Directory.Read.AllScopes: Reports.Read.All, Directory.Read.All
- Authentication Method ReportsAuthentication method reports
param(
[string]$OutputPath = ".\mfa-coverage-report.csv"
)
try {
# Use Graph reporting endpoint for MFA registration status
Import-Module Microsoft.Graph.Reports -ErrorAction Stop
Connect-MgGraph -Scopes "Reports.Read.All","Directory.Read.All" -NoWelcome -ErrorAction Stop
$details = Get-MgReportAuthenticationMethodUserRegistrationDetail -All
$report = $details | Select-Object UserPrincipalName, UserDisplayName, IsMfaRegistered, IsSsprRegistered,
@{Name='Methods';Expression={ ($_.MethodsRegistered -join '; ') }},
@{Name='DefaultMethod';Expression={$_.DefaultMfaMethod}},
@{Name='IsPasswordlessCapable';Expression={$_.IsPasswordlessCapable}}
$report | Export-Csv $OutputPath -NoTypeInformation -Encoding UTF8
}
catch {
Write-Error "MFA coverage report failed: $($_.Exception.Message)"
throw
}
finally {
Disconnect-MgGraph -ErrorAction SilentlyContinue | Out-Null
}
Service Principal Credential ReportService Principal Credential Report
Zeigt Zertifikate und Secrets aller Service Principals inklusive Ablaufdaten.Shows certificates and secrets for all service principals including expiry dates.
- Microsoft.Graph.ApplicationsMicrosoft.Graph.Applications
- Scopes: Application.Read.AllScopes: Application.Read.All
- Hilfreich für Secret RotationHelpful for secret rotation
param(
[string]$OutputPath = ".\service-principal-credential-report.csv"
)
try {
# Enumerate service principal credentials and normalize expiry output
Import-Module Microsoft.Graph.Applications -ErrorAction Stop
Connect-MgGraph -Scopes "Application.Read.All" -NoWelcome -ErrorAction Stop
$servicePrincipals = Get-MgServicePrincipal -All -Property Id,AppId,DisplayName,PasswordCredentials,KeyCredentials
$report = foreach ($sp in $servicePrincipals) {
foreach ($secret in $sp.PasswordCredentials) {
[pscustomobject]@{
DisplayName = $sp.DisplayName
AppId = $sp.AppId
CredentialType= 'Secret'
CredentialName= $secret.DisplayName
EndDateTime = $secret.EndDateTime
}
}
foreach ($cert in $sp.KeyCredentials) {
[pscustomobject]@{
DisplayName = $sp.DisplayName
AppId = $sp.AppId
CredentialType= 'Certificate'
CredentialName= $cert.DisplayName
EndDateTime = $cert.EndDateTime
}
}
}
$report | Sort-Object EndDateTime | Export-Csv $OutputPath -NoTypeInformation -Encoding UTF8
}
catch {
Write-Error "Service principal credential report failed: $($_.Exception.Message)"
throw
}
finally {
Disconnect-MgGraph -ErrorAction SilentlyContinue | Out-Null
}
Entra Connect Sync StatusEntra Connect Sync Status
Prüft lokal auf dem Sync-Server den Scheduler, letzte Läufe und bekannte Fehler.Checks the scheduler, recent runs, and known errors locally on the sync server.
- ADSync Modul auf dem Connect-ServerADSync module on the Connect server
- Lokale AdministratorrechteLocal administrator rights
- Direkt auf dem Sync-Server ausführenRun directly on the sync server
param(
[string]$OutputPath = ".\entra-connect-sync-status.csv"
)
try {
# Run directly on the Entra Connect server
Import-Module ADSync -ErrorAction Stop
$scheduler = Get-ADSyncScheduler
$runHistory = Get-ADSyncRunProfileResult -ConnectorId * -NumberRequested 20
$report = @(
[pscustomobject]@{ Metric = 'SyncCycleEnabled'; Value = $scheduler.SyncCycleEnabled },
[pscustomobject]@{ Metric = 'NextSyncCyclePolicyType'; Value = $scheduler.NextSyncCyclePolicyType },
[pscustomobject]@{ Metric = 'NextSyncCycleStartTime'; Value = $scheduler.NextSyncCycleStartTimeInUTC },
[pscustomobject]@{ Metric = 'PurgeRunHistoryInterval'; Value = $scheduler.PurgeRunHistoryInterval },
[pscustomobject]@{ Metric = 'LastSuccessfulRun'; Value = ($runHistory | Where-Object Result -eq 'success' | Select-Object -First 1).RunEndTime }
)
$report | Export-Csv $OutputPath -NoTypeInformation -Encoding UTF8
}
catch {
Write-Error "Entra Connect sync status failed: $($_.Exception.Message)"
throw
}
Compliance Policy Assignment ReportCompliance Policy Assignment Report
Zeigt Intune-Compliance-Policies samt zugewiesenen Gruppen.Shows Intune compliance policies together with assigned groups.
- Microsoft.Graph.DeviceManagementMicrosoft.Graph.DeviceManagement
- Scopes: DeviceManagementConfiguration.Read.All, Group.Read.AllScopes: DeviceManagementConfiguration.Read.All, Group.Read.All
- Intune AdministratorIntune Administrator
param(
[string]$OutputPath = ".\compliance-policy-assignments.csv"
)
try {
# Read Intune compliance policies and their assignments
Import-Module Microsoft.Graph.DeviceManagement -ErrorAction Stop
Connect-MgGraph -Scopes "DeviceManagementConfiguration.Read.All","Group.Read.All" -NoWelcome -ErrorAction Stop
$policies = Get-MgDeviceManagementDeviceCompliancePolicy -All
$report = foreach ($policy in $policies) {
foreach ($assignment in $policy.Assignments) {
[pscustomobject]@{
PolicyName = $policy.DisplayName
PolicyId = $policy.Id
Assignment = $assignment.Target.AdditionalProperties.'@odata.type'
GroupId = $assignment.Target.GroupId
}
}
}
$report | Export-Csv $OutputPath -NoTypeInformation -Encoding UTF8
}
catch {
Write-Error "Compliance policy assignment report failed: $($_.Exception.Message)"
throw
}
finally {
Disconnect-MgGraph -ErrorAction SilentlyContinue | Out-Null
}
Defender for Office 365 Config AuditDefender for Office 365 Config Audit
Prüft Safe Links, Safe Attachments und Anti-Phishing Basiskonfigurationen.Checks Safe Links, Safe Attachments, and anti-phishing baseline settings.
- ExchangeOnlineManagementExchangeOnlineManagement
- Security Administrator oder Exchange AdministratorSecurity Administrator or Exchange Administrator
- Defender for Office 365 lizenziertDefender for Office 365 licensed
param(
[string]$OutputPath = ".\defender-o365-config-audit.csv"
)
try {
# Collect baseline policy state from Exchange Online
Import-Module ExchangeOnlineManagement -ErrorAction Stop
Connect-ExchangeOnline -ShowBanner:$false -ErrorAction Stop
$report = @()
Get-SafeLinksPolicy | ForEach-Object {
$report += [pscustomobject]@{ Workload = 'SafeLinks'; Name = $_.Name; Enabled = $_.EnableSafeLinksForEmail; Detail = "TrackClicks=$($_.TrackClicks)" }
}
Get-SafeAttachmentPolicy | ForEach-Object {
$report += [pscustomobject]@{ Workload = 'SafeAttachments'; Name = $_.Name; Enabled = $true; Detail = "Action=$($_.Action)" }
}
Get-AntiPhishPolicy | ForEach-Object {
$report += [pscustomobject]@{ Workload = 'AntiPhish'; Name = $_.Name; Enabled = $true; Detail = "SpoofIntelligence=$($_.EnableSpoofIntelligence)" }
}
$report | Export-Csv $OutputPath -NoTypeInformation -Encoding UTF8
}
catch {
Write-Error "Defender config audit failed: $($_.Exception.Message)"
throw
}
finally {
Disconnect-ExchangeOnline -Confirm:$false -ErrorAction SilentlyContinue
}
DNS Record ValidatorDNS Record Validator
Validiert SPF, DKIM, DMARC, MX und Autodiscover für alle akzeptierten Domains.Validates SPF, DKIM, DMARC, MX, and Autodiscover for all accepted domains.
- ExchangeOnlineManagement oder CSV-DomainlisteExchangeOnlineManagement or CSV domain list
- Öffentlicher DNS-ZugriffPublic DNS resolution
- Kann ohne Microsoft Graph laufenCan run without Microsoft Graph
param(
[string]$OutputPath = ".\dns-validation-report.csv"
)
try {
# Pull accepted domains and resolve key M365 records
Import-Module ExchangeOnlineManagement -ErrorAction Stop
Connect-ExchangeOnline -ShowBanner:$false -ErrorAction Stop
$domains = Get-AcceptedDomain | Select-Object -ExpandProperty DomainName
$report = foreach ($domain in $domains) {
[pscustomobject]@{
Domain = $domain
SPF = (Resolve-DnsName -Name $domain -Type TXT -ErrorAction SilentlyContinue | Where-Object Strings -match 'v=spf1').Strings -join ' '
MX = (Resolve-DnsName -Name $domain -Type MX -ErrorAction SilentlyContinue | Select-Object -ExpandProperty NameExchange -First 1)
DMARC = (Resolve-DnsName -Name "_dmarc.$domain" -Type TXT -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Strings -First 1) -join ' '
DKIMSelector1 = (Resolve-DnsName -Name "selector1._domainkey.$domain" -Type CNAME -ErrorAction SilentlyContinue | Select-Object -ExpandProperty NameHost -First 1)
Autodiscover = (Resolve-DnsName -Name "autodiscover.$domain" -Type CNAME -ErrorAction SilentlyContinue | Select-Object -ExpandProperty NameHost -First 1)
}
}
$report | Export-Csv $OutputPath -NoTypeInformation -Encoding UTF8
}
catch {
Write-Error "DNS validation failed: $($_.Exception.Message)"
throw
}
finally {
Disconnect-ExchangeOnline -Confirm:$false -ErrorAction SilentlyContinue
}
User Sign-in Activity Heatmap DataUser Sign-in Activity Heatmap Data
Exportiert Anmeldedaten pro Wochentag und Stunde für Visualisierungen.Exports sign-in data by weekday and hour for visualizations.
- Microsoft.Graph.Identity.SignInsMicrosoft.Graph.Identity.SignIns
- Scopes: AuditLog.Read.AllScopes: AuditLog.Read.All
- Geeignet für Power BI / Excel HeatmapsSuitable for Power BI / Excel heatmaps
param(
[int]$Days = 30,
[string]$OutputPath = ".\signin-heatmap-data.csv"
)
try {
# Summarize sign-ins by weekday and hour
Import-Module Microsoft.Graph.Identity.SignIns -ErrorAction Stop
Connect-MgGraph -Scopes "AuditLog.Read.All" -NoWelcome -ErrorAction Stop
$since = (Get-Date).AddDays(-$Days).ToUniversalTime().ToString('s') + 'Z'
$signIns = Get-MgAuditLogSignIn -All -Filter "createdDateTime ge $since"
$heatmap = $signIns | Group-Object { "{0}-{1}" -f $_.CreatedDateTime.DayOfWeek, $_.CreatedDateTime.Hour } | ForEach-Object {
$parts = $_.Name.Split('-')
[pscustomobject]@{
Weekday = $parts[0]
Hour = [int]$parts[1]
SignInCount = $_.Count
}
}
$heatmap | Sort-Object Weekday, Hour | Export-Csv $OutputPath -NoTypeInformation -Encoding UTF8
}
catch {
Write-Error "Sign-in heatmap export failed: $($_.Exception.Message)"
throw
}
finally {
Disconnect-MgGraph -ErrorAction SilentlyContinue | Out-Null
}
Bulk Password Reset with Temporary Access PassBulk Password Reset with Temporary Access Pass
Setzt Kennwörter zurück und erstellt Temporary Access Passes für importierte Benutzer.Resets passwords and creates Temporary Access Passes for imported users.
- CSV mit UserPrincipalName, NewPasswordCSV with UserPrincipalName, NewPassword
- Microsoft.Graph.UsersMicrosoft.Graph.Users
- Benutzeradministrator oder Authentication AdministratorUser Administrator or Authentication Administrator
param(
[Parameter(Mandatory)]
[string]$InputCsv,
[string]$OutputPath = ".\bulk-password-reset-results.csv"
)
try {
# Reset password and create a Temporary Access Pass per user
Import-Module Microsoft.Graph.Users -ErrorAction Stop
Connect-MgGraph -Scopes "User.ReadWrite.All","UserAuthenticationMethod.ReadWrite.All" -NoWelcome -ErrorAction Stop
$users = Import-Csv $InputCsv -ErrorAction Stop
$report = foreach ($user in $users) {
Update-MgUser -UserId $user.UserPrincipalName -PasswordProfile @{ ForceChangePasswordNextSignIn = $true; Password = $user.NewPassword } -ErrorAction Stop
$tap = New-MgUserAuthenticationTemporaryAccessPassMethod -UserId $user.UserPrincipalName -BodyParameter @{ isUsableOnce = $true; lifetimeInMinutes = 60 } -ErrorAction Stop
[pscustomobject]@{
UserPrincipalName = $user.UserPrincipalName
PasswordReset = $true
TemporaryAccessPass = $tap.TemporaryAccessPass
TemporaryAccessPassId = $tap.Id
}
}
$report | Export-Csv $OutputPath -NoTypeInformation -Encoding UTF8
}
catch {
Write-Error "Bulk password reset failed: $($_.Exception.Message)"
throw
}
finally {
Disconnect-MgGraph -ErrorAction SilentlyContinue | Out-Null
}
Complete Tenant Security Posture ReportComplete Tenant Security Posture Report
Kombiniert MFA-Status, CA-Richtlinien, Admin-Rollen, Gastanzahl und inaktive Konten in einem Bericht.Combines MFA status, CA policies, admin roles, guest count, and inactive accounts in one report.
- Microsoft.Graph.Users + Reports + Identity.SignIns + Identity.GovernanceMicrosoft.Graph.Users + Reports + Identity.SignIns + Identity.Governance
- Mehrere Read-ScopesMultiple read scopes
- CSV + JSON ExportCSV + JSON export
param(
[string]$CsvOutputPath = ".\tenant-security-posture-summary.csv",
[string]$JsonOutputPath = ".\tenant-security-posture-details.json"
)
try {
# Gather security posture metrics from multiple Graph workloads
Import-Module Microsoft.Graph.Users, Microsoft.Graph.Reports, Microsoft.Graph.Identity.SignIns, Microsoft.Graph.Identity.Governance -ErrorAction Stop
Connect-MgGraph -Scopes "User.Read.All","Reports.Read.All","AuditLog.Read.All","Policy.Read.All","RoleManagement.Read.All" -NoWelcome -ErrorAction Stop
$users = Get-MgUser -All -Property Id,UserType,AccountEnabled,SignInActivity
$mfa = Get-MgReportAuthenticationMethodUserRegistrationDetail -All
$caPolicies = Get-MgIdentityConditionalAccessPolicy -All
$activeRoles = Get-MgRoleManagementDirectoryRoleAssignmentSchedule -All
$summary = @(
[pscustomobject]@{ Metric = 'TotalUsers'; Value = $users.Count },
[pscustomobject]@{ Metric = 'Guests'; Value = ($users | Where-Object UserType -eq 'Guest').Count },
[pscustomobject]@{ Metric = 'Inactive90Days'; Value = ($users | Where-Object { $_.SignInActivity.LastSuccessfulSignInDateTime -and ([datetime]$_.SignInActivity.LastSuccessfulSignInDateTime) -lt (Get-Date).AddDays(-90) }).Count },
[pscustomobject]@{ Metric = 'MfaRegistered'; Value = ($mfa | Where-Object IsMfaRegistered).Count },
[pscustomobject]@{ Metric = 'ConditionalAccessPolicies'; Value = $caPolicies.Count },
[pscustomobject]@{ Metric = 'PrivilegedAssignments'; Value = $activeRoles.Count }
)
$summary | Export-Csv $CsvOutputPath -NoTypeInformation -Encoding UTF8
$details = [pscustomobject]@{
GeneratedAt = Get-Date
Summary = $summary
Policies = $caPolicies | Select-Object DisplayName, State, CreatedDateTime, ModifiedDateTime
}
$details | ConvertTo-Json -Depth 10 | Set-Content -Path $JsonOutputPath -Encoding UTF8
}
catch {
Write-Error "Tenant security posture report failed: $($_.Exception.Message)"
throw
}
finally {
Disconnect-MgGraph -ErrorAction SilentlyContinue | Out-Null
}