In this post I will show how to retrieve paginated data from Azure AD using MS Graph .Net client library. As we already saw from previous examples (see e.g. Create Azure AD group and set group owner using Microsoft Graph Client library) client library is adopted for asynchronous usage (we can call its methods asynchronously using async/await C# keywords). In addition to that it also restricts number of objects returned from single request, e.g. when you get list of users via GraphServiceClient.Users.Request().GetAsync() call it will return only 100 users. In order to get other users we will need to load all pages by 100 users each. The following example shows how to do it:
1: static async void enumUsers()
2: {
3: var graph = new GraphServiceClient(new AzureAuthenticationProvider());
4: try
5: {
6: var users = await graph.Users.Request().GetAsync();
7: int requestNumber = 1;
8: while (users.Count > 0)
9: {
10: Console.WriteLine("Request number: {0}", requestNumber++);
11: foreach (var u in users)
12: {
13: Console.WriteLine("User: {0} ({1})", u.DisplayName,
14: u.UserPrincipalName);
15: }
16:
17: if (users.NextPageRequest != null)
18: {
19: users = await users.NextPageRequest.GetAsync();
20: }
21: else
22: {
23: break;
24: }
25: }
26: }
27: catch (ServiceException x)
28: {
29: Console.WriteLine("Exception occured: {0}", x.Error);
30: }
31: }
32:
33:
34:
35: public class AzureAuthenticationProvider : IAuthenticationProvider
36: {
37: public async Task AuthenticateRequestAsync(HttpRequestMessage request)
38: {
39: string clientId = ConfigurationManager.AppSettings["ClientId"];
40: string clientSecret = ConfigurationManager.AppSettings["ClientSecret"];
41: string authority = ConfigurationManager.AppSettings["AuthorityUrl"];
42:
43: AuthenticationContext authContext = new AuthenticationContext(authority);
44:
45: ClientCredential creds = new ClientCredential(clientId, clientSecret);
46:
47: Console.WriteLine("before: get token");
48: AuthenticationResult authResult = await
49: authContext.AcquireTokenAsync("https://graph.microsoft.com/", creds);
50: Console.WriteLine("after: get token {0}", authResult.AccessToken);
51:
52: request.Headers.Add("Authorization", "Bearer " + authResult.AccessToken);
53: }
54: }
I.e. we call graph.Users.Request().GetAsync() first (line 6) and then call graph.Users.NextPageRequest.GetAsync() (line 19) until next page won’t be empty. For convenience I also added number of request made to Graph API to the console (line 10) so it will be visible how many requests are needed for iterating through all users. For authentication we use application id and secret in custom AzureAuthenticationProvider as described in the following article: Work with Azure AD via Microsoft Graph API.
erratum: async/wait -> async/Await
ReplyDeleteof course, thank you, I updated the post
ReplyDeleteI am not able to get users more than 999 by this code
ReplyDeleteashwin,
Deletewhat page size do you use?
I have 1000 users on my azure account
ReplyDeleteAs per microsoft document we can pull max 999 users so this code by default pull 999 users from azure ad what about next 1 user i am not able to get it by this code
you just pull 999 users and create list using users.NextPageRequest parameter
can you help me on this.
ReplyDeletepublic static async Task> GetUsersAsync()
{
var graphClient = GetAuthenticatedClient();
List allUsers = new List();
var users = await graphClient.Users.Request().Top(998)
.Select("displayName,mail,givenName,surname,id")
.GetAsync();
while (users.Count > 0)
{
allUsers.AddRange(users);
if (users.NextPageRequest != null)
{
users = await users.NextPageRequest
.GetAsync();
}
else
{
break;
}
}
return allUsers;
}
This code is workable.