Export more than 100,000 Entra logs at same time
- romanvitsinskyi
- Jun 11
- 2 min read
Updated: Jun 24
Entra ID has hard-coded limit of 100,000 when downloading sign-in or provisioning logs from Entra Portal. The workaround for this limitation is PowerShell code below, utilizing Graph API and nextLink feature.
You need to have at least AuditLog.Read.All Graph API permission and Global Reader Entra Role.
Hope you'll find it useful
$logsResponse = Invoke-MgGraphRequest -Uri "https://graph.microsoft.com/beta/auditLogs/signins" -Method GET $date = get-date -UFormat "%Y-%m-%d_%H.%M" $logsResponse.value | % { $log = $_ [pscustomobject] @{ DateTime = $log.createdDateTime userDisplayName = $log.userDisplayName userPrincipalName = $log.userPrincipalName ipAddress = $log.ipAddress appDisplayName = $log.appDisplayName clientAppUsed = $log.clientAppUsed userAgent = $log.userAgent isInteractive = $log.isInteractive conditionalAccessStatus = $log.conditionalAccessStatus authenticationRequirement = $log.authenticationRequirement 'MFA AuthMethod' = $log.MfaDetail.AuthMethod 'MFA AuthDetail' = $log.MfaDetail.AuthDetail 'Error Code' = $log.status.errorCode FailureReason = $log.status.failureReason additionalDetails = $log.status.additionalDetails CountryOrRegion = $log.location.countryOrRegion state = $log.location.state city = $log.location.city Browser = $log.deviceDetail.browser DeviceId = $log.deviceDetail.deviceId DisplayName = $log.deviceDetail.displayName isCompliant = $log.deviceDetail.isCompliant isManaged = $log.deviceDetail.isManaged operatingSystem = $log.deviceDetail.operatingSystem trustType = $log.deviceDetail.trustType networkType = $($log.networkLocationDetails.networkType | out-string) networkNames = $($log.networkLocationDetails.networkNames | out-string) riskState = $log.riskState } | export-csv c:\temp\aad_signins_$($date).csv -NoTypeInformation -Append } $nextLink = $logsResponse.'@odata.nextLink' while ($NextLink -ne $null) { $logsResponse = Invoke-MgGraphRequest -Uri $NextLink -Method GET $NextLink = $logsResponse."@odata.nextLink" $logsResponse.value | % { $log = $_ [pscustomobject] @{ DateTime = $log.createdDateTime userDisplayName = $log.userDisplayName userPrincipalName = $log.userPrincipalName ipAddress = $log.ipAddress appDisplayName = $log.appDisplayName clientAppUsed = $log.clientAppUsed userAgent = $log.userAgent isInteractive = $log.isInteractive conditionalAccessStatus = $log.conditionalAccessStatus authenticationRequirement = $log.authenticationRequirement 'MFA AuthMethod' = $log.MfaDetail.AuthMethod 'MFA AuthDetail' = $log.MfaDetail.AuthDetail 'Error Code' = $log.status.errorCode FailureReason = $log.status.failureReason additionalDetails = $log.status.additionalDetails CountryOrRegion = $log.location.countryOrRegion state = $log.location.state city = $log.location.city Browser = $log.deviceDetail.browser DeviceId = $log.deviceDetail.deviceId DisplayName = $log.deviceDetail.displayName isCompliant = $log.deviceDetail.isCompliant isManaged = $log.deviceDetail.isManaged operatingSystem = $log.deviceDetail.operatingSystem trustType = $log.deviceDetail.trustType networkType = $($log.networkLocationDetails.networkType | out-string) networkNames = $($log.networkLocationDetails.networkNames | out-string) riskState = $log.riskState } | export-csv c:\temp\aad_signins_$($date).csv -NoTypeInformation -Append } } |