Cloud Scripts
Ready-to-run PowerShell scripts for Exchange Online, Microsoft 365, and Entra ID. Edit variables inline, copy to clipboard, or download as a .ps1 file.
Get Mailbox Rules & Descriptions
Lists all inbox rules for a mailbox including name, enabled state, conditions, and actions. Useful for spotting auto-forward or deletion rules.
Exchange Online
ExchangeOnlineManagement
Required Module
Install-Module ExchangeOnlineManagement -Force
Connect First
Connect-ExchangeOnline -UserPrincipalName ##ADMIN_UPN##
Edit Variables
Admin UPN
Mailbox email
Script
Get-InboxRule -Mailbox "##MAILBOX##" |
Select-Object Name, Enabled, Description,
@{N="Conditions";E={$_.Conditions | Out-String}},
@{N="Actions";E={$_.Actions | Out-String}} |
Format-List
Get All External Forwarding Rules
Finds all mailboxes that are forwarding email externally — either via ForwardingSmtpAddress or inbox rules. Critical for security audits.
Exchange Online
ExchangeOnlineManagement
Required Module
Install-Module ExchangeOnlineManagement -Force
Connect First
Connect-ExchangeOnline -UserPrincipalName ##ADMIN_UPN##
Edit Variables
Admin UPN
Script
# Mailbox-level forwarding
Get-Mailbox -ResultSize Unlimited |
Where-Object { $_.ForwardingSmtpAddress -ne $null } |
Select-Object DisplayName, UserPrincipalName, ForwardingSmtpAddress, DeliverToMailboxAndForward |
Format-Table -AutoSize
# Inbox rule forwarding
Get-Mailbox -ResultSize Unlimited | ForEach-Object {
$rules = Get-InboxRule -Mailbox $_.UserPrincipalName -ErrorAction SilentlyContinue |
Where-Object { $_.ForwardTo -or $_.RedirectTo -or $_.ForwardAsAttachmentTo }
if ($rules) {
Write-Host "Mailbox: $($_.UserPrincipalName)" -ForegroundColor Yellow
$rules | Select-Object Name, ForwardTo, RedirectTo | Format-List
}
}
Get Mailbox Size & Item Count
Reports mailbox size, item count, and quota status for all mailboxes or a specific user. Sorted by size descending.
Exchange Online
ExchangeOnlineManagement
Required Module
Install-Module ExchangeOnlineManagement -Force
Connect First
Connect-ExchangeOnline -UserPrincipalName ##ADMIN_UPN##
Edit Variables
Admin UPN
Script
Get-Mailbox -ResultSize Unlimited |
Get-MailboxStatistics |
Select-Object DisplayName,
@{N="Size (MB)"; E={[math]::Round($_.TotalItemSize.Value.ToMB(), 2)}},
ItemCount,
@{N="Deleted (MB)"; E={[math]::Round($_.TotalDeletedItemSize.Value.ToMB(), 2)}},
LastLogonTime |
Sort-Object "Size (MB)" -Descending |
Format-Table -AutoSize
Get All Email Aliases (Proxy Addresses)
Lists every email address and alias across all mailboxes. Useful for finding alias conflicts or auditing email addresses in use.
Exchange Online
ExchangeOnlineManagement
Required Module
Install-Module ExchangeOnlineManagement -Force
Connect First
Connect-ExchangeOnline -UserPrincipalName ##ADMIN_UPN##
Edit Variables
Admin UPN
Script
Get-Mailbox -ResultSize Unlimited | ForEach-Object {
$mb = $_
$mb.EmailAddresses | Where-Object { $_ -like "smtp:*" } | ForEach-Object {
[PSCustomObject]@{
DisplayName = $mb.DisplayName
UPN = $mb.UserPrincipalName
Type = $mb.RecipientTypeDetails
EmailAddress = $_ -replace "smtp:", ""
IsPrimary = $_ -clike "SMTP:*"
}
}
} | Sort-Object DisplayName | Format-Table -AutoSize
Remove User From All Groups
Removes a departing user from all distribution lists and mail-enabled security groups in Exchange Online.
Exchange Online
ExchangeOnlineManagement
Required Module
Install-Module ExchangeOnlineManagement -Force
Connect First
Connect-ExchangeOnline -UserPrincipalName ##ADMIN_UPN##
Edit Variables
Admin UPN
Departing user
Script
$upn = "##USER_UPN##"
$groups = Get-Recipient -ResultSize Unlimited -RecipientTypeDetails MailUniversalDistributionGroup, MailUniversalSecurityGroup |
Where-Object { (Get-DistributionGroupMember -Identity $_.Identity -ResultSize Unlimited).PrimarySmtpAddress -contains $upn }
if ($groups.Count -eq 0) {
Write-Host "No groups found for $upn" -ForegroundColor Yellow
} else {
foreach ($group in $groups) {
Remove-DistributionGroupMember -Identity $group.Identity -Member $upn -Confirm:$false
Write-Host "Removed from: $($group.DisplayName)" -ForegroundColor Green
}
Write-Host "`nTotal groups removed from: $($groups.Count)" -ForegroundColor Cyan
}
Get Mailbox Delegate Permissions
Reports all non-default FullAccess, SendAs, and SendOnBehalf permissions across all mailboxes.
Exchange Online
ExchangeOnlineManagement
Required Module
Install-Module ExchangeOnlineManagement -Force
Connect First
Connect-ExchangeOnline -UserPrincipalName ##ADMIN_UPN##
Edit Variables
Admin UPN
Script
$report = @()
$mailboxes = Get-Mailbox -ResultSize Unlimited
foreach ($mb in $mailboxes) {
# FullAccess
Get-MailboxPermission -Identity $mb.Identity |
Where-Object { $_.AccessRights -like "*FullAccess*" -and !$_.IsInherited -and $_.User -notlike "NT AUTHORITY*" } |
ForEach-Object {
$report += [PSCustomObject]@{
Mailbox = $mb.PrimarySmtpAddress
Delegate = $_.User
Permission = "FullAccess"
}
}
# SendAs
Get-RecipientPermission -Identity $mb.Identity |
Where-Object { $_.Trustee -notlike "NT AUTHORITY*" } |
ForEach-Object {
$report += [PSCustomObject]@{
Mailbox = $mb.PrimarySmtpAddress
Delegate = $_.Trustee
Permission = "SendAs"
}
}
# SendOnBehalf
$mb.GrantSendOnBehalfTo | ForEach-Object {
$report += [PSCustomObject]@{
Mailbox = $mb.PrimarySmtpAddress
Delegate = $_
Permission = "SendOnBehalf"
}
}
}
$report | Sort-Object Mailbox | Format-Table -AutoSize
Block User Sign-In
Disables a user account to prevent sign-in. Use for leavers or compromised accounts. Does not delete the account or affect their mailbox.
Entra ID / M365
Microsoft.Graph
Required Module
Install-Module Microsoft.Graph -Force
Connect First
Connect-MgGraph -Scopes 'User.ReadWrite.All'
Edit Variables
User UPN to block
Script
$upn = "##USER_UPN##" # Block sign-in Update-MgUser -UserId $upn -AccountEnabled:$false # Revoke all active sessions Revoke-MgUserSignInSession -UserId $upn Write-Host "Blocked sign-in and revoked sessions for: $upn" -ForegroundColor Green # Verify Get-MgUser -UserId $upn | Select-Object DisplayName, UserPrincipalName, AccountEnabled
Get MFA Status for All Users
Reports the MFA registration status for all users, including authentication methods registered. Uses Microsoft Graph.
Entra ID / M365
Microsoft.Graph
Required Module
Install-Module Microsoft.Graph -Force
Connect First
Connect-MgGraph -Scopes 'UserAuthenticationMethod.Read.All', 'User.Read.All'
Script
$users = Get-MgUser -All -Property DisplayName, UserPrincipalName, AccountEnabled
$report = foreach ($user in $users) {
$methods = Get-MgUserAuthenticationMethod -UserId $user.Id
$methodTypes = $methods.AdditionalProperties."@odata.type" -replace "#microsoft.graph.", ""
[PSCustomObject]@{
DisplayName = $user.DisplayName
UPN = $user.UserPrincipalName
AccountEnabled = $user.AccountEnabled
MFAMethodCount = $methods.Count
Methods = ($methodTypes | Where-Object { $_ -ne "passwordAuthenticationMethod" }) -join ", "
HasMFA = ($methods.Count -gt 1)
}
}
$report | Sort-Object HasMFA, DisplayName | Format-Table -AutoSize
Write-Host "`nUsers without MFA: $(($report | Where-Object { !$_.HasMFA }).Count)" -ForegroundColor Yellow
Write-Host "Users with MFA: $(($report | Where-Object { $_.HasMFA }).Count)" -ForegroundColor Green
Get Last Sign-In Date for All Users
Reports the last interactive sign-in for every user. Useful for identifying inactive accounts.
Entra ID / M365
Microsoft.Graph
Required Module
Install-Module Microsoft.Graph -Force
Connect First
Connect-MgGraph -Scopes 'User.Read.All', 'AuditLog.Read.All'
Script
Get-MgUser -All -Property DisplayName, UserPrincipalName, AccountEnabled, SignInActivity |
Select-Object DisplayName, UserPrincipalName, AccountEnabled,
@{N="LastSignIn"; E={$_.SignInActivity.LastSignInDateTime}},
@{N="DaysSinceSignIn"; E={
if ($_.SignInActivity.LastSignInDateTime) {
(New-TimeSpan -Start $_.SignInActivity.LastSignInDateTime -End (Get-Date)).Days
} else { "Never" }
}} |
Sort-Object LastSignIn -Descending |
Format-Table -AutoSize
Find Inactive Users (No Sign-In)
Lists users who have not signed in within a specified number of days. Useful for licence cleanup and security audits.
Entra ID / M365
Microsoft.Graph
Required Module
Install-Module Microsoft.Graph -Force
Connect First
Connect-MgGraph -Scopes 'User.Read.All', 'AuditLog.Read.All'
Edit Variables
Days of inactivity
Users who have not signed in for this many days
Script
$inactiveDays = ##DAYS##
$cutoff = (Get-Date).AddDays(-$inactiveDays)
Get-MgUser -All -Property DisplayName, UserPrincipalName, AccountEnabled, SignInActivity |
Where-Object {
$_.AccountEnabled -eq $true -and (
$_.SignInActivity.LastSignInDateTime -lt $cutoff -or
$null -eq $_.SignInActivity.LastSignInDateTime
)
} |
Select-Object DisplayName, UserPrincipalName,
@{N="LastSignIn"; E={$_.SignInActivity.LastSignInDateTime ?? "Never"}},
@{N="DaysInactive"; E={
if ($_.SignInActivity.LastSignInDateTime) {
(New-TimeSpan -Start $_.SignInActivity.LastSignInDateTime -End (Get-Date)).Days
} else { "Never signed in" }
}} |
Sort-Object LastSignIn |
Format-Table -AutoSize
Get All Licensed Users
Lists all users with assigned licences, showing which licence SKUs are assigned to each account.
Entra ID / M365
Microsoft.Graph
Required Module
Install-Module Microsoft.Graph -Force
Connect First
Connect-MgGraph -Scopes 'User.Read.All'
Script
# Get friendly SKU name mapping
$skuMap = @{}
Get-MgSubscribedSku | ForEach-Object { $skuMap[$_.SkuId] = $_.SkuPartNumber }
Get-MgUser -All -Property DisplayName, UserPrincipalName, AccountEnabled, AssignedLicenses |
Where-Object { $_.AssignedLicenses.Count -gt 0 } |
Select-Object DisplayName, UserPrincipalName, AccountEnabled,
@{N="Licences"; E={
($_.AssignedLicenses | ForEach-Object { $skuMap[$_.SkuId] ?? $_.SkuId }) -join ", "
}} |
Sort-Object DisplayName |
Format-Table -AutoSize
$total = (Get-MgUser -All -Filter "assignedLicenses/`$count ne 0" -ConsistencyLevel eventual -CountVariable c; $c)
Write-Host "`nTotal licensed users: $total" -ForegroundColor Cyan
Force Password Reset at Next Sign-In
Forces a user to change their password the next time they sign in. Does not change the current password.
Entra ID / M365
Microsoft.Graph
Required Module
Install-Module Microsoft.Graph -Force
Connect First
Connect-MgGraph -Scopes 'User.ReadWrite.All'
Edit Variables
User UPN
Script
$upn = "##USER_UPN##"
Update-MgUser -UserId $upn -PasswordProfile @{
ForceChangePasswordNextSignIn = $true
}
Write-Host "Password reset flag set for: $upn" -ForegroundColor Green
Write-Host "User will be prompted to change password on next sign-in." -ForegroundColor Yellow
Get All Admin Role Members
Lists every admin role in the tenant and all users assigned to each role. Useful for access reviews and privilege audits.
Entra ID / M365
Microsoft.Graph
Required Module
Install-Module Microsoft.Graph -Force
Connect First
Connect-MgGraph -Scopes 'RoleManagement.Read.Directory', 'User.Read.All'
Script
$roles = Get-MgDirectoryRole -All
foreach ($role in $roles | Sort-Object DisplayName) {
$members = Get-MgDirectoryRoleMember -DirectoryRoleId $role.Id
if ($members.Count -gt 0) {
Write-Host "`n=== $($role.DisplayName) ===" -ForegroundColor Cyan
$members | ForEach-Object {
$user = Get-MgUser -UserId $_.Id -ErrorAction SilentlyContinue
if ($user) {
Write-Host " $($user.DisplayName) <$($user.UserPrincipalName)>"
}
}
}
}
Get All Guest Users
Lists all guest (external) accounts in the tenant with their invite status and last sign-in date.
Entra ID / M365
Microsoft.Graph
Required Module
Install-Module Microsoft.Graph -Force
Connect First
Connect-MgGraph -Scopes 'User.Read.All', 'AuditLog.Read.All'
Script
Get-MgUser -All -Filter "userType eq 'Guest'" -Property DisplayName, UserPrincipalName, Mail, CreatedDateTime, SignInActivity |
Select-Object DisplayName, UserPrincipalName, Mail,
@{N="Created"; E={$_.CreatedDateTime}},
@{N="LastSignIn"; E={$_.SignInActivity.LastSignInDateTime ?? "Never"}} |
Sort-Object Created -Descending |
Format-Table -AutoSize
Revoke All User Sessions
Immediately invalidates all active sign-in sessions and refresh tokens for a user. Use for compromised accounts.
Entra ID / M365
Microsoft.Graph
Required Module
Install-Module Microsoft.Graph -Force
Connect First
Connect-MgGraph -Scopes 'User.ReadWrite.All'
Edit Variables
User UPN
Script
$upn = "##USER_UPN##" Revoke-MgUserSignInSession -UserId $upn Write-Host "All sessions revoked for: $upn" -ForegroundColor Green Write-Host "The user will be signed out of all apps and devices immediately." -ForegroundColor Yellow # Also block sign-in if this is a security incident # Update-MgUser -UserId $upn -AccountEnabled:$false
Get All Conditional Access Policies
Lists all Conditional Access policies with their state, included/excluded users, and conditions.
Entra ID / M365
Microsoft.Graph
Required Module
Install-Module Microsoft.Graph -Force
Connect First
Connect-MgGraph -Scopes 'Policy.Read.All'
Script
Get-MgIdentityConditionalAccessPolicy -All |
Select-Object DisplayName, State,
@{N="IncludeUsers"; E={$_.Conditions.Users.IncludeUsers -join ", "}},
@{N="ExcludeUsers"; E={$_.Conditions.Users.ExcludeUsers -join ", "}},
@{N="IncludeApps"; E={$_.Conditions.Applications.IncludeApplications -join ", "}},
@{N="GrantControls"; E={$_.GrantControls.BuiltInControls -join ", "}} |
Format-List
M365 Licence Usage Summary
Shows each subscribed SKU, total seats, consumed seats, and remaining seats. Handy for licence capacity checks.
Entra ID / M365
Microsoft.Graph
Required Module
Install-Module Microsoft.Graph -Force
Connect First
Connect-MgGraph -Scopes 'Organization.Read.All'
Script
Get-MgSubscribedSku |
Select-Object SkuPartNumber,
@{N="Total"; E={$_.PrepaidUnits.Enabled}},
ConsumedUnits,
@{N="Available"; E={$_.PrepaidUnits.Enabled - $_.ConsumedUnits}} |
Sort-Object SkuPartNumber |
Format-Table -AutoSize
Get Disabled Cloud Users
Lists disabled Entra user accounts with UPN and creation date. Useful for leaver and stale-account reviews.
Entra ID / M365
Microsoft.Graph
Required Module
Install-Module Microsoft.Graph -Force
Connect First
Connect-MgGraph -Scopes 'User.Read.All'
Script
Get-MgUser -All -Property DisplayName,UserPrincipalName,AccountEnabled,CreatedDateTime |
Where-Object { $_.AccountEnabled -eq $false } |
Select-Object DisplayName, UserPrincipalName, CreatedDateTime |
Sort-Object DisplayName |
Format-Table -AutoSize
Get User Authentication Methods
Lists registered authentication methods for a user (Authenticator app, phone, FIDO2, etc).
Entra ID / M365
Microsoft.Graph
Required Module
Install-Module Microsoft.Graph -Force
Connect First
Connect-MgGraph -Scopes 'UserAuthenticationMethod.Read.All', 'User.Read.All'
Edit Variables
User UPN
Script
$upn = "##USER_UPN##"
$user = Get-MgUser -UserId $upn -ErrorAction SilentlyContinue
if (-not $user) {
Write-Host "User not found: $upn" -ForegroundColor Red
return
}
Get-MgUserAuthenticationMethod -UserId $user.Id |
Select-Object Id,
@{N="MethodType"; E={$_.AdditionalProperties."@odata.type" -replace "#microsoft.graph.",""}} |
Format-Table -AutoSize
Get Mailbox Auto-Reply Status
Reports automatic reply (out-of-office) configuration for all user mailboxes.
Exchange Online
ExchangeOnlineManagement
Required Module
Install-Module ExchangeOnlineManagement -Force
Connect First
Connect-ExchangeOnline -UserPrincipalName ##ADMIN_UPN##
Edit Variables
Admin UPN
Script
Get-Mailbox -RecipientTypeDetails UserMailbox -ResultSize Unlimited |
ForEach-Object {
$ar = Get-MailboxAutoReplyConfiguration -Identity $_.UserPrincipalName
[PSCustomObject]@{
DisplayName = $_.DisplayName
UserPrincipalName= $_.UserPrincipalName
AutoReplyState = $ar.AutoReplyState
InternalMessage = $ar.InternalMessage
ExternalMessage = $ar.ExternalMessage
}
} |
Sort-Object DisplayName |
Format-Table -AutoSize
Get Locked Out AD Accounts
Finds all currently locked-out Active Directory accounts with the lockout time and source DC.
Active Directory
ActiveDirectory
Required Module
Install-WindowsFeature RSAT-AD-PowerShell # Server # Or for Windows 10/11: Add-WindowsCapability -Online -Name Rsat.ActiveDirectory.DS-LDS.Tools~~~~0.0.1.0
Connect First
# Run on a Domain Controller or machine with RSAT installed
Script
Search-ADAccount -LockedOut |
Get-ADUser -Properties LockedOut, BadLogonCount, BadPasswordTime, LastBadPasswordAttempt |
Select-Object Name, SamAccountName, LockedOut, BadLogonCount, LastBadPasswordAttempt |
Format-Table -AutoSize
Unlock AD Account
Unlocks a locked Active Directory user account.
Active Directory
ActiveDirectory
Required Module
Install-WindowsFeature RSAT-AD-PowerShell # Server # Or for Windows 10/11: Add-WindowsCapability -Online -Name Rsat.ActiveDirectory.DS-LDS.Tools~~~~0.0.1.0
Connect First
# Run on a Domain Controller or machine with RSAT installed
Edit Variables
SAM account name
Script
$samAccount = "##SAM_ACCOUNT##"
Unlock-ADAccount -Identity $samAccount
Write-Host "Unlocked account: $samAccount" -ForegroundColor Green
# Verify
Get-ADUser -Identity $samAccount -Properties LockedOut, BadLogonCount |
Select-Object Name, SamAccountName, LockedOut, BadLogonCount
Find Inactive AD Users
Lists enabled AD user accounts that have not logged on within a specified number of days.
Active Directory
ActiveDirectory
Required Module
Install-WindowsFeature RSAT-AD-PowerShell # Server # Or for Windows 10/11: Add-WindowsCapability -Online -Name Rsat.ActiveDirectory.DS-LDS.Tools~~~~0.0.1.0
Connect First
# Run on a Domain Controller or machine with RSAT installed
Edit Variables
Days of inactivity
Script
$inactiveDays = ##DAYS##
$cutoff = (Get-Date).AddDays(-$inactiveDays)
Get-ADUser -Filter { Enabled -eq $true } -Properties LastLogonDate, Description |
Where-Object { $_.LastLogonDate -lt $cutoff -or $_.LastLogonDate -eq $null } |
Select-Object Name, SamAccountName, LastLogonDate, Description |
Sort-Object LastLogonDate |
Format-Table -AutoSize
Get AD Group Members
Lists all members of a specified Active Directory group, including nested group resolution.
Active Directory
ActiveDirectory
Required Module
Install-WindowsFeature RSAT-AD-PowerShell # Server # Or for Windows 10/11: Add-WindowsCapability -Online -Name Rsat.ActiveDirectory.DS-LDS.Tools~~~~0.0.1.0
Connect First
# Run on a Domain Controller or machine with RSAT installed
Edit Variables
Group name
Script
$groupName = "##GROUP_NAME##"
# Direct members
Write-Host "Direct members of: $groupName" -ForegroundColor Cyan
Get-ADGroupMember -Identity $groupName | Get-ADUser -Properties EmailAddress |
Select-Object Name, SamAccountName, EmailAddress | Format-Table -AutoSize
# All members including nested
Write-Host "`nAll members (including nested groups):" -ForegroundColor Cyan
Get-ADGroupMember -Identity $groupName -Recursive | Get-ADUser -Properties EmailAddress |
Select-Object Name, SamAccountName, EmailAddress | Format-Table -AutoSize
Reset AD Password & Force Change
Resets an Active Directory user password and forces them to change it at next logon.
Active Directory
ActiveDirectory
Required Module
Install-WindowsFeature RSAT-AD-PowerShell # Server # Or for Windows 10/11: Add-WindowsCapability -Online -Name Rsat.ActiveDirectory.DS-LDS.Tools~~~~0.0.1.0
Connect First
# Run on a Domain Controller or machine with RSAT installed
Edit Variables
SAM account name
Temporary password
Must meet your domain password policy
Script
$samAccount = "##SAM_ACCOUNT##" $newPassword = ConvertTo-SecureString "##TEMP_PASSWORD##" -AsPlainText -Force Set-ADAccountPassword -Identity $samAccount -NewPassword $newPassword -Reset Set-ADUser -Identity $samAccount -ChangePasswordAtLogon $true Write-Host "Password reset for: $samAccount" -ForegroundColor Green Write-Host "User must change password at next logon." -ForegroundColor Yellow
Get Recently Created AD Accounts
Lists AD user accounts created within the last N days. Useful for onboarding audits.
Active Directory
ActiveDirectory
Required Module
Install-WindowsFeature RSAT-AD-PowerShell # Server # Or for Windows 10/11: Add-WindowsCapability -Online -Name Rsat.ActiveDirectory.DS-LDS.Tools~~~~0.0.1.0
Connect First
# Run on a Domain Controller or machine with RSAT installed
Edit Variables
Created in last N days
Script
$days = ##DAYS##
$cutoff = (Get-Date).AddDays(-$days)
Get-ADUser -Filter { WhenCreated -ge $cutoff } -Properties WhenCreated, EmailAddress, Description |
Select-Object Name, SamAccountName, WhenCreated, EmailAddress, Description |
Sort-Object WhenCreated -Descending |
Format-Table -AutoSize
Get Local Disk Free Space
Shows local fixed drives with total size, free space, and free percentage. Great for proactive storage checks.
Local Windows
Built-in
Required Module
# No module install required (built into Windows PowerShell)
Connect First
# Run in an elevated PowerShell session on the target machine
Script
Get-CimInstance Win32_LogicalDisk -Filter "DriveType=3" |
Select-Object DeviceID,
@{N="Size (GB)"; E={[math]::Round($_.Size / 1GB, 2)}},
@{N="Free (GB)"; E={[math]::Round($_.FreeSpace / 1GB, 2)}},
@{N="Free %"; E={[math]::Round(($_.FreeSpace / $_.Size) * 100, 1)}} |
Sort-Object "Free %" |
Format-Table -AutoSize
Get Local Administrators Group Members
Lists all members of the local Administrators group. Useful for privilege auditing on endpoints and servers.
Local Windows
Built-in
Required Module
# No module install required (built into Windows PowerShell)
Connect First
# Run in an elevated PowerShell session on the target machine
Script
Get-LocalGroupMember -Group "Administrators" |
Select-Object Name, ObjectClass, PrincipalSource |
Sort-Object Name |
Format-Table -AutoSize
Get Top CPU Processes (Live Sample)
Samples process CPU usage over a short interval and returns the top CPU consumers.
Local Windows
Built-in
Required Module
# No module install required (built into Windows PowerShell)
Connect First
# Run in PowerShell on the target machine
Edit Variables
Sample duration (seconds)
Script
$sampleSeconds = ##SECONDS##
$before = Get-Process | Select-Object Id, ProcessName, CPU
Start-Sleep -Seconds $sampleSeconds
$after = Get-Process | Select-Object Id, ProcessName, CPU
$report = foreach ($p in $after) {
$old = $before | Where-Object { $_.Id -eq $p.Id }
if ($old -and $p.CPU -ne $null -and $old.CPU -ne $null) {
[PSCustomObject]@{
ProcessName = $p.ProcessName
Id = $p.Id
CpuSeconds = [math]::Round(($p.CPU - $old.CPU), 2)
}
}
}
$report | Sort-Object CpuSeconds -Descending | Select-Object -First 15 | Format-Table -AutoSize
Get Automatic Services Not Running
Finds services set to Automatic startup that are currently stopped.
Local Windows
Built-in
Required Module
# No module install required (built into Windows PowerShell)
Connect First
# Run in PowerShell on the target machine
Script
Get-Service |
Where-Object { $_.StartType -eq "Automatic" -and $_.Status -ne "Running" } |
Select-Object Name, DisplayName, Status, StartType |
Sort-Object DisplayName |
Format-Table -AutoSize
Find Suspicious Mailbox Rules
Scans all mailboxes for potentially malicious inbox rules — rules that forward externally, delete messages, or redirect silently. Common indicator of compromise.
Exchange Online
ExchangeOnlineManagement
Required Module
Install-Module ExchangeOnlineManagement -Force
Connect First
Connect-ExchangeOnline -UserPrincipalName ##ADMIN_UPN##
Edit Variables
Admin UPN
Script
$suspicious = @()
Get-Mailbox -ResultSize Unlimited | ForEach-Object {
$mbx = $_
Get-InboxRule -Mailbox $mbx.UserPrincipalName -ErrorAction SilentlyContinue |
Where-Object {
$_.ForwardTo -or $_.RedirectTo -or $_.ForwardAsAttachmentTo -or
$_.DeleteMessage -eq $true -or $_.MoveToFolder -ne $null
} | ForEach-Object {
$suspicious += [PSCustomObject]@{
Mailbox = $mbx.UserPrincipalName
RuleName = $_.Name
Enabled = $_.Enabled
ForwardTo = $_.ForwardTo -join "; "
RedirectTo = $_.RedirectTo -join "; "
DeleteMsg = $_.DeleteMessage
MoveToFolder = $_.MoveToFolder
}
}
}
if ($suspicious.Count -eq 0) {
Write-Host "No suspicious rules found." -ForegroundColor Green
} else {
Write-Host "WARNING: $($suspicious.Count) suspicious rule(s) found!" -ForegroundColor Red
$suspicious | Format-List
}
Search M365 Unified Audit Log
Searches the Microsoft 365 unified audit log for admin and user activity. Results are limited to 5000 records; narrow your date range for large tenants.
Exchange Online
ExchangeOnlineManagement
Required Module
Install-Module ExchangeOnlineManagement -Force
Connect First
Connect-ExchangeOnline -UserPrincipalName ##ADMIN_UPN##
Edit Variables
Admin UPN
Look back (days)
Script
$startDate = (Get-Date).AddDays(-##DAYS##).ToString("yyyy-MM-dd")
$endDate = (Get-Date).ToString("yyyy-MM-dd")
$results = Search-UnifiedAuditLog `
-StartDate $startDate `
-EndDate $endDate `
-ResultSize 500
$results |
Select-Object CreationDate, UserIds, Operations, AuditData |
Sort-Object CreationDate -Descending |
Format-Table -AutoSize
Write-Host "`nTotal records: $($results.Count)" -ForegroundColor Cyan
Get App Registrations & Permissions
Lists all Azure AD app registrations and their assigned API permissions. Important for security audits and app inventory.
Entra ID / M365
Microsoft.Graph
Required Module
Install-Module Microsoft.Graph -Force
Connect First
Connect-MgGraph -Scopes 'Application.Read.All'
Script
$apps = Get-MgApplication -All
foreach ($app in $apps | Sort-Object DisplayName) {
Write-Host "`n=== $($app.DisplayName) ===" -ForegroundColor Cyan
Write-Host " App ID: $($app.AppId)"
Write-Host " Created: $($app.CreatedDateTime)"
if ($app.RequiredResourceAccess) {
Write-Host " API Permissions:" -ForegroundColor Yellow
foreach ($resource in $app.RequiredResourceAccess) {
Write-Host " Resource: $($resource.ResourceAppId)"
$resource.ResourceAccess | ForEach-Object {
Write-Host " $($_.Type): $($_.Id)"
}
}
}
}
Get Recent Sign-In Failures
Retrieves failed sign-in events from Entra ID logs. Useful for detecting brute-force attacks or account compromise attempts.
Entra ID / M365
Microsoft.Graph
Required Module
Install-Module Microsoft.Graph -Force
Connect First
Connect-MgGraph -Scopes 'AuditLog.Read.All'
Edit Variables
Look back (hours)
Script
$startTime = (Get-Date).AddHours(-##HOURS##).ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ")
Get-MgAuditLogSignIn -Filter "status/errorCode ne 0 and createdDateTime ge $startTime" -All |
Select-Object CreatedDateTime, UserPrincipalName,
@{N="Error"; E={$_.Status.FailureReason}},
@{N="IP"; E={$_.IpAddress}},
@{N="Location"; E={"$($_.Location.City), $($_.Location.CountryOrRegion)"}},
@{N="AppName"; E={$_.AppDisplayName}} |
Sort-Object CreatedDateTime -Descending |
Format-Table -AutoSize
Get All Teams & Owners
Lists all Microsoft Teams in the tenant with their owners, member count, and visibility setting.
Entra ID / M365
Microsoft.Graph
Required Module
Install-Module Microsoft.Graph -Force
Connect First
Connect-MgGraph -Scopes 'Group.Read.All', 'User.Read.All'
Script
$teams = Get-MgGroup -Filter "resourceProvisioningOptions/Any(x:x eq 'Team')" -All `
-Property Id, DisplayName, Description, Visibility, CreatedDateTime
foreach ($team in $teams | Sort-Object DisplayName) {
$owners = Get-MgGroupOwner -GroupId $team.Id
$members = Get-MgGroupMember -GroupId $team.Id -All
[PSCustomObject]@{
Team = $team.DisplayName
Visibility = $team.Visibility
Members = $members.Count
Owners = ($owners | ForEach-Object {
(Get-MgUser -UserId $_.Id -ErrorAction SilentlyContinue).UserPrincipalName
}) -join "; "
Created = $team.CreatedDateTime
}
} | Format-Table -AutoSize
No scripts match your search.
Frequently asked questions
How do I use these scripts?
Fill in any variables shown above the script, then click Copy or Download .ps1. Run the script in PowerShell 5.1+ or PowerShell 7. Most scripts require a module to be installed first — the required module and install command are shown on each card.
Do I need to connect before running each script?
Yes. Each script group shows a Connect command at the top. For Exchange Online, run Connect-ExchangeOnline first. For Microsoft Graph, run Connect-MgGraph with the required scopes. For Azure AD legacy, run Connect-AzureAD.
Are these scripts safe to run in production?
All scripts are read-only (Get-* commands) unless explicitly described as making changes. Scripts that modify settings or block accounts are clearly labelled. Always test in a non-production environment first and ensure you have appropriate permissions.