๐ก๏ธ Recipe ยท Security & Compliance
Generate a weekly VIP/admin sign-in anomaly report
Detect unusual sign-in patterns for privileged and executive accounts in Microsoft 365
Complexity
Intermediate
Impact
security + compliance + monitoring + privileged-access + reporting
Context
Why This Matters
VIP accounts (executives, board members) and privileged admin accounts are the highest-value targets in any Microsoft 365 tenant. Attackers routinely use password spray, credential stuffing, and session hijacking against these identities, and a single compromise can lead to tenant-wide impact.
A weekly sign-in anomaly report gives your security team a rhythm for catching early-stage attacks โ repeated failures, impossible-travel events, sign-ins from unfamiliar geographies, and abnormal activity frequency โ before they escalate into incidents. Running this on a schedule (rather than only reacting to alerts) ensures coverage of low-and-slow attacks that might not trigger Conditional Access or Identity Protection in real time.
Run this recipe every Monday morning as part of your security operations cadence, or any time after a known threat campaign targeting executives.
Expected Outcomes
- A consolidated list of all directory role holders (admins) and members of VIP/Executive/Leadership groups
- Sign-in log analysis for each VIP/admin covering the past 7 days
- Anomaly flags: โฅ5 failed sign-ins, sign-ins from new countries, sign-ins outside business hours, sign-ins at abnormal frequency
- A prioritized list of accounts requiring follow-up (password reset, session revoke, MFA re-registration, or user contact)
- A CSV/HTML report suitable for sharing with the security team and leadership
Risks & Considerations
Compliance & Privacy
- Sign-in logs contain IP addresses and location data โ treat the report as confidential and store it in a controlled location
- Some jurisdictions (EU/GDPR) require that access to employee sign-in data be logged and justified
Operational Gotchas
- AuditLog.Read.All is a sensitive permission โ grant it only to a dedicated service principal or reporting account, never to an interactive user unnecessarily
- Sign-in logs are retained for 30 days on Entra ID P1/P2 licenses. Tenants on free tier only retain 7 days
- "Unfamiliar location" is subjective โ baseline at least 30 days of sign-in history before flagging first-seen countries as anomalous, or you'll get false positives for business travelers
- Service accounts and break-glass accounts may appear as anomalies by design โ maintain an allow-list
What NOT to do
- Don't auto-disable accounts based on this report โ always have a human confirm before taking account actions on executives
- Don't email the raw report to distribution lists; it's a disclosure risk
Required Permissions
| Permission | Why It's Needed |
|---|---|
| RoleManagement.Read.Directory | List members of directory roles (Global Admin, Security Admin, etc.) to identify privileged accounts |
| Group.Read.All | Enumerate VIP/Executive/Leadership groups and their members |
| AuditLog.Read.All | Read sign-in logs to analyze authentication patterns and failures |
| User.Read.All | Resolve user details (display name, UPN, department) for the report |
The fastest way to get this done: just ask Dex. Copy the prompt below and paste it into your Dex conversation.
For IT Admins
Paste into Dex Pro
Generate the report via the Entra admin center
This GUI path produces the report section-by-section; for full automation use the API or PowerShell paths.
Step 1 โ Identify admin accounts
- Sign in to entra.microsoft.com as a Security Reader or Global Reader
- Navigate to
- For each privileged role (Global Administrator, Privileged Role Administrator, Security Administrator, Exchange Administrator, SharePoint Administrator, User Administrator), click the role and export the member list
- Consolidate into a single spreadsheet of admin UPNs
Step 2 โ Identify VIP group members
- Navigate to
- Search for groups containing "VIP", "Executive", or "Leadership"
- Open each group and export members; add UPNs to the same spreadsheet
Step 3 โ Review sign-in logs per account
- Navigate to
- Set the date range to Last 7 days
- Add filter: User = {vip_upn}
- For each VIP/admin, review:
- Status column โ count Failure entries (โฅ5 is a flag)
- Location column โ note any new countries versus their usual pattern
- IP address โ look for datacenter/VPN/Tor exit ranges
- Switch to the User sign-ins (non-interactive) tab to catch token replay activity
- Export each filtered view as CSV
Step 4 โ Compile and recommend
- For any account with flags, recommend: password reset, revoke all sessions (), re-register MFA, or direct contact with the user
- Save the report to your security team's secure location
Note: For tenants with >10 VIP/admin accounts the manual path becomes impractical โ use PowerShell instead.
Build the report via Microsoft Graph API
The report assembly involves four API calls: enumerate roles, enumerate VIP groups, pull sign-in logs, and correlate.
1. List all directory role members (admins)
GET https://graph.microsoft.com/v1.0/directoryRoles?$expand=members($select=id,displayName,userPrincipalName)Response contains one entry per activated role with a members collection. Flatten and dedupe by userPrincipalName.
2. Find VIP/Executive groups and their members
GET https://graph.microsoft.com/v1.0/groups?$filter=contains(displayName,'VIP') or contains(displayName,'Executive') or contains(displayName,'Leadership')&$select=id,displayNameThen for each group ID:
GET https://graph.microsoft.com/v1.0/groups/{group_id}/members?$select=id,displayName,userPrincipalName3. Query sign-in logs for the past 7 days
Use a filter that scopes to the target UPN and a 7-day window:
GET https://graph.microsoft.com/v1.0/auditLogs/signIns?$filter=userPrincipalName eq '{upn}' and createdDateTime ge {iso_7_days_ago}&$top=1000Key fields to inspect in each sign-in record:
status.errorCodeโ non-zero = failurelocation.countryOrRegion,location.cityipAddressriskLevelAggregated,riskState(requires Entra ID P2)clientAppUsed,deviceDetail
4. Apply anomaly rules
Aggregate per user and flag when:
- Failed sign-in count โฅ 5 in the window
countryOrRegionnot seen in the prior 30 days for that user- Sign-ins outside of 6amโ10pm user local time
riskLevelAggregated=mediumorhigh
Example anomaly response (simplified)
{
"user": "ceo@contoso.com",
"failures_7d": 12,
"new_countries": ["RU", "CN"],
"risky_signins": 2,
"recommendation": "Revoke sessions, reset password, contact user"
}Required application permissions: RoleManagement.Read.Directory, Group.Read.All, AuditLog.Read.All, User.Read.All. Grant admin consent before first run.
Run the report with PowerShell + Microsoft Graph SDK
The Microsoft.Graph PowerShell module handles auth, paging, and JSON parsing โ ideal for a weekly scheduled task.
Prerequisites
Install-Module Microsoft.Graph -Scope CurrentUser
Install-Module Microsoft.Graph.Beta -Scope CurrentUser # optional, for risk signalsConnect with the right scopes
Connect-MgGraph -Scopes "RoleManagement.Read.Directory","Group.Read.All","AuditLog.Read.All","User.Read.All"What the script does
- Enumerates all active directory roles and collects member UPNs
- Finds groups whose display name matches VIP/Executive/Leadership keywords
- For each VIP/admin UPN, pulls sign-in logs for the last 7 days via
Get-MgAuditLogSignIn - Applies anomaly rules: failure count, new countries vs 30-day baseline, risky sign-ins
- Produces a CSV and an HTML report with a recommendations column
Scheduling
Run the downloadable script weekly via a scheduled task on a hardened management workstation, or as an Azure Automation runbook using a managed identity with the required app permissions consented.
The script emits two files: VIP-SignIn-Anomalies-{yyyyMMdd}.csv (raw data) and VIP-SignIn-Anomalies-{yyyyMMdd}.html (executive summary).
Next steps