'Powershell Get-AzureADAuditSignInLogs Limits

I'm using Get-AzureADAuditSignInLogs from the AzureADPreview Module. This cmdlet limits its output to 1000 lines. I thought doing a workaround and ask it by User/Date filter. It would work in my case but then I'm hitting a http429 error like this.

Error occurred while executing GetAuditSignInLogs 
Code: UnknownError
Message: Too Many Requests
InnerError:
  RequestId: fc532b20-baea-4f62-8b5a-f4714f86f0a9
  DateTimeStamp: Wed, 10 Nov 2021 14:40:35 GMT
HttpStatusCode: 429
HttpStatusDescription: Too Many Requests
HttpResponseStatus: Completed

I've seen techniques on how to query the number of request you can still make within a given time, but that was all when you launch http-requests. I suppose the module is masking that for us.

Does anybody know a technique on how to do this with this module ?

This is the code

Write-Output ("--- Get All AAD SignOns ---")
$filterDate = "{0:yyyy-MM-dd}" -f (get-date).AddDays(-30)
$TempFileName = $TempDir + $storageblobpath + $FileName + "AADSignOn.csv"
$usrCount     = 0
$logCount     = 0

ForEach ($user in $users) {
    $usrCount++
    $signons = Get-AzureADAuditSignInLogs -Filter "createdDateTime ge $filterDate and userPrincipalName eq '$user.UserPrincipalName'" |
                Select-Object Id,CreatedDateTime,UserId,AppId,AppDisplayName,IpAddress,ClientAppUsed,IsInteractive,TokenIssuerType,ProcessingTimeInMilliseconds,
                    @{name='DeviceId';expression={$_.DeviceDetail.DeviceId} },
                    @{name='DeviceDisplayName';expression={$_.DeviceDetail.DisplayName} },
                    @{name='DeviceOperatingSystem';expression={$_.DeviceDetail.OperatingSystem} },
                    @{name='DeviceBrowser';expression={$_.DeviceDetail.Browser} },
                    @{name='DeviceIsCompliant';expression={$_.DeviceDetail.IsCompliant} },
                    @{name='DeviceIsManaged';expression={$_.DeviceDetail.IsManaged} },
                    @{name='DeviceTrustType';expression={$_.DeviceDetail.TrustType} },
                    @{name='LocationCity';expression={$_.Location.City} },
                    @{name='LocationState';expression={$_.Location.State} },
                    @{name='LocationCountryOrRegion';expression={$_.Location.CountryOrRegion} }
    $signons | Export-Csv -Path $TempFileName -NoTypeInformation -Append

    $logCount += $signons.Count                   
    if ($usrCount % 200 -eq 0) {
        Write-Output ("Users {0}, {1} Logs so far" -f $usrCount, $logCount)
    }
}

Kr, Harry



Solution 1:[1]

I got the same error from looping through a set of users in my environment. Now i've not tested this extensively, but adding a delay to each request seems to bypass this error in my case at least.

I simply added Start-Sleep -Milliseconds 500 to the end of each request. Granted my user-base wasn't that large so this might add significant time to your loop, but the errors did not occur afterwards.

Edit: Running a try/catch statement and only delaying upon error i found to be a faster way than a consistent delay.

    try {
        $UPN = $entry.Trim()
        Get-AzureADAuditSignInLogs -Filter "UserPrincipalName eq '$UPN'" | select UserPrincipalName,CreatedDateTime -Last 1 | Out-File -FilePath $login_file -Append
    }
    catch {
        $UPN = $entry.Trim()
        Start-Sleep -Seconds 20
        Get-AzureADAuditSignInLogs -Filter "UserPrincipalName eq '$UPN'" | select UserPrincipalName,CreatedDateTime -Last 1 | Out-File -FilePath $login_file -Append
    }

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1