For years, defenders relied on MicrosoftGraphActivityLogs to monitor Graph API activity in Microsoft Entra ID. However, this visibility was incomplete because the table only captures requests to Microsoft Graph (graph.microsoft.com) and does not include activity against the legacy Azure AD Graph endpoint (graph.windows.net). The newly introduced AADGraphActivityLogs table closes this long-standing telemetry gap.
The missing visibility relates to the legacy Azure AD Graph API, which is still used by many enterprise applications, including some Microsoft services.
For security teams, threat hunters, and SOC analysts, this significantly improves detection visibility.
Why another table?
Many defenders assumed that monitoring MicrosoftGraphActivityLogs meant they had visibility into all Graph-related activity within their tenant. In reality, this is not true. Time to make it clear.
In reality, MicrosoftGraphActivityLogs only captures traffic to Microsoft Graph (graph.microsoft.com).
It does not provide visibility into requests made to the legacy Azure AD Graph API (graph.windows.net).
The distinction is important:
| Log Table | API Endpoint |
|---|---|
| MicrosoftGraphActivityLogs | graph.microsoft.com |
| AADGraphActivityLogs | graph.windows.net (Legacy Azure AD Graph) |
This separation created a telemetry gap that attackers and security assessment tools could unintentionally or deliberately leverage.
Why is this still in use?
A large number of well-known Azure AD reconnaissance and assessment tools were built around the legacy Azure AD Graph API. Just some popular toolings that were using the legacy API.
- AADInternals
- ROADtools / ROADrecon
- Ping Castle
These tools are commonly used by:
- Red teams
- Penetration testers
- Adversaries performing cloud reconnaissance
- Security consultants assessing identity posture
Because many of these tools communicate directly with graph.windows.net, their activity often never appeared in MicrosoftGraphActivityLogs, since, as already explained, the API used in the toolings is the legacy graph.windows.net API.
As a result, organizations could have significant identity reconnaissance activity occurring in their environment while SOC analysts remained unaware because they were monitoring only Microsoft Graph telemetry or were focusing on Defender (EDR/AV) alerts.
So why are we making such a big deal about a log for an API that Microsoft has been trying to retire for years? Attackers still love old legacy Azure AD Graph APIs, since there is no logging. And no logs means no visibility, and without visibility, there is no detection.
Why Legacy Azure AD Graph Still Matters
Despite Microsoft’s push toward Microsoft Graph, many environments continue to have dependencies on Azure AD Graph. Common reasons include:
Legacy Enterprise Applications
Applications developed years ago may still depend on Azure AD Graph APIs and have never been modernized.
Older Automation Scripts
PowerShell scripts, custom tooling, and operational automations often continue running long after their original deployment.
Deprecated Integrations
Third-party products sometimes maintain legacy integrations for compatibility reasons.
Technical Debt
Organizations frequently discover Azure AD Graph dependencies only when they begin migration projects or API retirement efforts.
AADGraphActivityLogs
The new AADGraphActivityLogs table finally provides defenders with visibility into traffic directed at the legacy Azure AD Graph endpoint. That means security teams can now detect legacy reconnaissance activity and improve their threat/ detection capabilities.
Many organizations are unaware of how much legacy Azure AD Graph usage still exists within their environments. The new table can help identify:
- Legacy enterprise applications
- Old automation workflows
- Deprecated scripts
- Outdated integrations
When enabling the audit logs, it can provide direct logging into the legacy graph telemetry. Based on the logging, usage can be detected.
How to connect the new source?
The new logging can be enabled as part of the Entra Diagnostic settings. Entra -> Diagnostic settings. In the available log categories, you can find the AzureADGraphActivityLogs
The following graph-related logs are available in the diagnostic settings:
| Table | What it Captures | API / Service |
|---|---|---|
| MicrosoftGraphActivityLogs | Requests made to Microsoft Graph | graph.microsoft.com |
| AzureADGraphActivityLogs | Requests made to legacy Azure AD Graph | graph.windows.net |
| GraphNotificationsActivityLogs | Graph change notifications (webhooks/subscriptions) | Microsoft Graph subscriptions |
| MicrosoftGraphPolicyLogs | Policy enforcement and governance actions related to Graph access | Microsoft Graph |
| PreAuthenticationDiscoveryLogs | Discovery activity occurring before authentication, often used during reconnaissance or app discovery workflows | Identity/Graph-related discovery processes |
As SOC reference:
| Question | Table |
|---|---|
| Who queried Microsoft Graph? | MicrosoftGraphActivityLogs |
| Who queried Azure AD Graph? | AzureADGraphActivityLogs |
| Who created Graph webhooks/subscriptions? | GraphNotificationsActivityLogs |
| Why was Graph access allowed or governed? | MicrosoftGraphPolicyLogs |
| Who performed tenant/user discovery before login? | PreAuthenticationDiscoveryLogs |
Select the AzureADGraphActivityLogs checkbox and send the logs to your Log Analytics workspace. Once enabled, all Azure AD Graph activity logs will be ingested into the selected Log Analytics workspace.

Logging and detections
The logs are stored in the AADGraphActivityLogs table within Log Analytics. Microsoft has published official documentation that includes the table schema and serves as a useful reference:
Azure Monitor Logs reference – AADGraphActivityLogs | Microsoft Learn
At a high level, this table is similar to MicrosoftGraphActivityLogs, although there are some notable differences. For example, IpAddress in AADGraphActivityLogs corresponds to CallerIpAddress in MicrosoftGraphActivityLogs.
For now, I will not go into advanced detail on the detection capabilities and queries. For a deeper understanding of the schema and practical detection examples, refer to the blogs listed below, which provide detailed explanations and sample queries.
Another good read by Truls on infernux.no: AADGraphActivityLogs in Microsoft Sentinel
And for detections, check the blog created by Fabian Bader. Now You See Me: AADGraphActivityLogs – Cloudbrothers
How to generate some sample data?
To generate data in the old API, I use AADInternals and ROADtools. You can use AADInternals to generate a request and then validate that it appears in the AADGraphActivityLogs table.

For example:
# Ensure Azure CLI is available and logged in:
# az login
# Install AADInternals if needed
if (-not (Get-Module -ListAvailable -Name AADInternals)) {
Install-Module AADInternals -Scope CurrentUser -Force
}
# Import module
Import-Module AADInternals -Force
# Get module path
$modulePath = (Get-Module AADInternals -ListAvailable |
Sort-Object Version -Descending |
Select-Object -First 1).ModuleBase
Write-Host "AADInternals path: $modulePath" -ForegroundColor Cyan
# Load required dependencies
$requiredFiles = @(
"CommonUtils.ps1",
"AccessToken_utils.ps1",
"AccessToken.ps1",
"GraphAPI_utils.ps1",
"GraphAPI.ps1"
)
foreach ($file in $requiredFiles) {
$fullPath = Join-Path $modulePath $file
if (Test-Path $fullPath) {
. $fullPath
Write-Host "Loaded $file" -ForegroundColor Green
}
else {
Write-Warning "$file not found"
}
}
# Verify required functions exist
$requiredFunctions = @(
"Read-Accesstoken",
"Is-AccessTokenExpired",
"Get-TenantDetails",
"Get-AADUsers",
"Get-Devices"
)
foreach ($func in $requiredFunctions) {
if (-not (Get-Command $func -ErrorAction SilentlyContinue)) {
throw "Required function '$func' was not loaded."
}
}
# Get Azure AD Graph token
$token = az account get-access-token `
--resource https://graph.windows.net `
--query accessToken `
-o tsv
if ([string]::IsNullOrWhiteSpace($token)) {
throw "Failed to obtain access token from Azure CLI."
}
Write-Host "Token acquired. Length: $($token.Length)" -ForegroundColor Green
# Tenant Details
Write-Host "`n=== Tenant Details ===" -ForegroundColor Cyan
Get-TenantDetails -AccessToken $token
# Users
Write-Host "`n=== First 10 Users ===" -ForegroundColor Cyan
Get-AADUsers -AccessToken $token |
Select-Object -First 10 |
Format-Table DisplayName,UserPrincipalName -AutoSize
# Devices
Write-Host "`n=== First 10 Devices ===" -ForegroundColor Cyan
Get-Devices -AccessToken $token |
Select-Object -First 10 |
Format-Table DisplayName,ObjectId -AutoSize
This command uses the legacy Azure AD Graph endpoint and should generate an entry in AADGraphActivityLogs if logging is enabled. The PowerShell script receives a couple of data files, including AADusers/ Devices and tenant details.
AADGraphActivityLogs
| where TimeGenerated > ago(1h)
| where UserAgent has "AADInternals"

More detailed explanations of how to run advanced commands with AADInternals or ROADtools can be found in other blogs. Above is just an example of how to generate logs
Data lake
When cost optimization is a priority, it is possible to route the AADGraphActivityLogs table directly to the Data Lake storage tier instead of ingesting all data into Log Analytics. This approach ensures that all Graph activity logs are retained in a cost-effective storage layer while avoiding the high ingestion and retention costs associated with large log volumes.

To maintain detection visibility, organizations can leverage KQL jobs or Summary Rules to process the raw data and ingest only the relevant events, aggregates, or security findings into Log Analytics. For example, to filter on the user agent to split suspicious activity from the normal graph API activity.
Conclusion
The introduction of AADGraphActivityLogs closes a long-standing visibility gap in Entra ID monitoring. While Azure AD Graph is considered legacy technology, it remains widely used by older applications, automation workflows, and security assessment tools.
Defenders can now identify these dependencies, improve migration efforts, and detect reconnaissance activity that previously operated with limited visibility. Organizations relying on MicrosoftGraphActivityLogs should review their diagnostic settings and consider enabling AzureADGraphActivityLogs to gain a more complete picture of Graph API activity across their tenant.