Get All The Users In An O365 Organization Using Graph API

In this article, I would like to explain and share the NodeJS code to get all the users from O365 using Graph API and will also discuss how to validate the raph api users results again the o365 admin portal.

In this article, I would like to explain and share the NodeJS code to get all the users from O365 using Graph API and we will see how to validate the Graph API user results with the O365 Admin Portal.

What is Microsoft Graph API?

It is a developer platform API that is used to get the data from O365 Azure, Outlook, SharePoint, Intune, Skype, OneDrive etc. It gives you a single REST API endpoint to interact with the Office 365.

From Microsoft documentation:

“Microsoft Graph is the gateway to data and intelligence in Microsoft 365. Microsoft Graph provides a unified programmability model that you can use to take advantage of the tremendous amount of data in Office 365, Enterprise Mobility + Security, and Windows 10.

You can use the Microsoft Graph API to build apps for organizations and consumers that interact with the data of millions of users. With Microsoft Graph, you can connect to a wealth of resources, relationships, and intelligence, all through a single endpoint: https://graph.microsoft.com

Reference URL - https://developer.microsoft.com/en-us/graph/docs/concepts/overview

Steps to use O365 to get all the users in an organization

Follow the below-listed steps and code,

End Point for user’s API - https://graph.microsoft.com/V1.0/users

Graph Token URL - https://login.microsoftonline.com/{tenantID}/oauth2/v2.0/token

Graph Token body - client_id=" + configValues.clientId + "&scope=" + configValues.scope + "&client_secret=" + configValues.clientSecretId + "&grant_type=client_credentials

Step 1

Register the app in Azure AD using that client ID, Tenant ID, and secret key.

Follow the below URL to Register the app in Azure.

Make sure to check that your registered Azure app has permission to read the directory data.

Step 2

In your node js solution just create the config file and provide the below values. We have created the config file to avoid the hard-coded things. Provide your tenantId , clientId and secret key don't use the below mentioned one , it is just sample (it won't work)
  1. {  
  2. "scope""https%3A%2F%2Fgraph.microsoft.com%2F.default",  
  3.  "tenantId""7aa111ae-1ab6-4256-af4c-a0c1cdb4575d",  
  4.  "clientId""bff7fae8-c253-37e5-9b6a-e096bed54f11",  
  5.  "clientSecretId""XgfrmWfX0K/N7SRouCdAskTKrz0cnKN2rS12IkJ9SJk="  
  6. }  

Step 3

Refer to that config file in your js file, as shown below,
  1. var request = require('sync-request');  
  2. var fs = require('fs');  
  3. var configValues = JSON.parse(fs.readFileSync('UsersConfig.json'));  

Step 4

Then frame the Graph token URL and Graph token body to get the auth token,
  1. var graphAccessUrl = "https://login.microsoftonline.com/" + configValues.tenantId + "/oauth2/v2.0/token";  
  2.         var graphTokenBody = "client_id=" + configValues.clientId + "&scope=" + configValues.scope + "&client_secret=" + configValues.clientSecretId + "&grant_type=client_credentials";  

Step 4

Get the Authorized token using the below method,
  1. var contentType = "application/x-www-form-urlencoded; charset=utf-8";  
  2. var graphTokenError = "Failed to get graph token";  
  3. var graphToken = "";  
  4. //Call the get token method  
  5. getToken(graphAccessUrl, contentType, graphTokenBody, graphTokenError);  
  6. //This method is using to get the token from the graph token url and body  
  7. function getToken(url, type, content, errorMessage, callback) {  
  8.     var options = {  
  9.         'headers':  
  10.         {  
  11.             'Content-Type': type  
  12.         },  
  13.         'body': content  
  14.     };  
  15.   
  16.     //Posting access parameters to the server  
  17.     var tokenResponse = httpPost(url, options);  
  18.   
  19.     if (tokenResponse.statusCode === 200) {  
  20.         error = errorMessage;  
  21.         if (errorMessage === graphTokenError) {  
  22.             var token = JSON.parse(tokenResponse.body.toString('utf-8'));  
  23.             graphToken = token.access_token;  
  24.         }  
  25.         if (callback) {  
  26.             return callback();  
  27.         }  
  28.     } else {  
  29.         Console.log(errorMessage);  
  30.     }  
  31. }  

Step 5

Once you received the token then do the http call using the EndPoint and get the results,

Note
In a single API call, we are able to get only 100 users so pass the top ten API endpoints to get up to 1000 users. If you have more than 1000 users, we can use the next link to get another 1000 users.

https://graph.microsoft.com/V1.0/users?$top=999

Nextlink is like pagination - On the response, you can pass this string to get the next set of users,

  1. var nextLink = "@odata.nextLink";    
How To Register An App In Azure Active Directory 
  1.  reqUrl = https://graph.microsoft.com/V1.0/users?$top=999  
  2. //call the get users method after you received the token in mail function  
  3. function getUsers(reqUrl) {  
  4.     try {  
  5.         var userList = [];  
  6.         console.log(MESSAGE + "Inside get users data method!!!");   
  7. //While condition is added to get more than 1000 users     
  8.         while(reqUrl)  
  9.         {  
  10.         var usersResponse = httpGet(reqUrl, graphToken);  
  11.         if (usersResponse.statusCode == 200) {  
  12.             failIndex = 0;  
  13.             var responseBlob = JSON.parse(usersResponse.body.toString('utf-8'));  
  14.             var parsedJsonres = responseBlob.value;  
  15.             userList = parsedJsonres;  
  16.             // add use case value to user collection [array]  
  17.             for (var i = 0; i < parsedJsonres.length; i++) {  
  18.                 var currItem = parsedJsonres[i];  
  19.                 if (currItem) {  
  20.                     bindUsers(currItem);  
  21.                 }  
  22.             }  
  23. //check whether the next link is available if so we have another set of users  
  24.             if (responseBlob[nextLink]) {  
  25.                 reqUrl=responseBlob[nextLink];                
  26.                continue;  
  27.             }  
  28.             else {  
  29.                 console.log(MESSAGE + "There is no next page..")  
  30.                 break;  
  31.             }  
  32.         }  
  33.         else {  
  34.             if (usersResponse.statusCode === 401 && JSON.parse(usersResponse.body.toString('utf-8'))["error"]["message"] === "Access token has expired.") {  
  35.                 getToken(graphAccessUrl, contentType, graphTokenBody, graphTokenError);  
  36.                 userList = userDetails.concat(getUsers(responseBlob[nextLink]));  
  37.             }  
  38.             else {  
  39.                 failIndex++;  
  40.                 if (failIndex == retryCount) {  
  41.                     console.log(errorMessage + "User API Call has been failed..");  
  42.                     failIndex = 0;  
  43.                 }  
  44.                 else  
  45.                     userList = userDetails.concat(getUsers(responseBlob[nextLink]));  
  46.             }  
  47.         }  
  48.     }  
  49.   
  50.     }  
  51.     catch (ex) {  
  52.         console.log(EXCEPTION_MESSAGE + ex);  
  53.     }  
  54.     return userList;  
  55. }  
  56. //Http method   
  57. function httpGet(url, bearerToken) {  
  58.     var request = require('sync-request');  
  59.     var res = request('GET', url,  
  60.         {  
  61.             'headers': {  
  62.                 'Authorization''Bearer ' + bearerToken,  
  63.                 'Accept'"application/json"  
  64.             }  
  65.         }  
  66.     );  
  67.     return res;  
  68. }  

Step 6

Then, bind the results based on your requirement. You will receive the below object when you call the user's API.

Version 1.0

How To Register An App In Azure Active Directory 

Beta API - Available columns

  1. {  
  2.             "id""24144c99-354b-4190-8d62-8ba7d2671939",  
  3.             "deletedDateTime"null,  
  4.             "accountEnabled"true,  
  5.             "ageGroup"null,  
  6.             "businessPhones": [],  
  7.             "city"null,  
  8.             "createdDateTime""2018-09-06T08:22:28Z",  
  9.             "companyName"null,  
  10.             "consentProvidedForMinor"null,  
  11.             "country"null,  
  12.             "department"null,  
  13.             "displayName""Test 10",  
  14.             "employeeId"null,  
  15.             "faxNumber"null,  
  16.             "givenName""Test",  
  17.             "imAddresses": [  
  18.                 "10@apptiodemo.onmicrosoft.com"  
  19.             ],  
  20.             "isResourceAccount"null,  
  21.             "jobTitle"null,  
  22.             "legalAgeGroupClassification"null,  
  23.             "mail""10@apptiodemo.onmicrosoft.com",  
  24.             "mailNickname""10",  
  25.             "mobilePhone"null,  
  26.             "onPremisesDistinguishedName"null,  
  27.             "officeLocation"null,  
  28.             "onPremisesDomainName"null,  
  29.             "onPremisesImmutableId"null,  
  30.             "onPremisesLastSyncDateTime"null,  
  31.             "onPremisesSecurityIdentifier"null,  
  32.             "onPremisesSamAccountName"null,  
  33.             "onPremisesSyncEnabled"null,  
  34.             "onPremisesUserPrincipalName"null,  
  35.             "otherMails": [],  
  36.             "passwordPolicies""None",  
  37.             "passwordProfile"null,  
  38.             "postalCode"null,  
  39.             "preferredDataLocation"null,  
  40.             "preferredLanguage"null,  
  41.             "proxyAddresses": [  
  42.                 "SMTP:10@apptiodemo.onmicrosoft.com"  
  43.             ],  
  44.             "refreshTokensValidFromDateTime""2018-09-06T08:22:28Z",  
  45.             "showInAddressList"null,  
  46.             "state"null,  
  47.             "streetAddress"null,  
  48.             "surname""10",  
  49.             "usageLocation""US",  
  50.             "userPrincipalName""10@apptiodemo.onmicrosoft.com",  
  51.             "externalUserState"null,  
  52.             "externalUserStateChangeDateTime"null,  
  53.             "userType""Member",  
  54.             "assignedLicenses": [  
  55.                 {  
  56.                     "disabledPlans": [],  
  57.                     "skuId""6fd2c87f-b296-42f0-b197-1e91e994b900"  
  58.                 }  
  59.             ],  
  60.             "assignedPlans": [  
  61.                 {  
  62.                     "assignedDateTime""2018-09-06T08:22:28Z",  
  63.                     "capabilityStatus""Deleted",  
  64.                     "service""exchange",  
  65.                     "servicePlanId""efb87545-963c-4e0d-99df-69c6916d9eb0"  
  66.                 },  
  67.                 {  
  68.                     "assignedDateTime""2018-09-06T08:22:28Z",  
  69.                     "capabilityStatus""Deleted",  
  70.                     "service""SharePoint",  
  71.                     "servicePlanId""5dbe027f-2339-4123-9542-606e4d348a72"  
  72.                 },  
  73.                 {  
  74.                     "assignedDateTime""2018-09-06T08:22:28Z",  
  75.                     "capabilityStatus""Deleted",  
  76.                     "service""SharePoint",  
  77.                     "servicePlanId""e95bec33-7c88-4a70-8e19-b10bd9d0c014"  
  78.                 },  
  79.                 {  
  80.                     "assignedDateTime""2018-09-06T08:22:28Z",  
  81.                     "capabilityStatus""Deleted",  
  82.                     "service""MicrosoftCommunicationsOnline",  
  83.                     "servicePlanId""0feaeb32-d00e-4d66-bd5a-43b5b83db82c"  
  84.                 },  
  85.                 {  
  86.                     "assignedDateTime""2018-09-06T08:22:28Z",  
  87.                     "capabilityStatus""Deleted",  
  88.                     "service""MicrosoftOffice",  
  89.                     "servicePlanId""43de0ff5-c92c-492b-9116-175376d08c38"  
  90.                 },  
  91.                 {  
  92.                     "assignedDateTime""2018-09-06T08:22:28Z",  
  93.                     "capabilityStatus""Deleted",  
  94.                     "service""RMSOnline",  
  95.                     "servicePlanId""bea4c11e-220a-4e6d-8eb8-8ea15d019f90"  
  96.                 },  
  97.                 {  
  98.                     "assignedDateTime""2018-09-06T08:22:28Z",  
  99.                     "capabilityStatus""Deleted",  
  100.                     "service""YammerEnterprise",  
  101.                     "servicePlanId""7547a3fe-08ee-4ccb-b430-5077c5041653"  
  102.                 },  
  103.                 {  
  104.                     "assignedDateTime""2018-09-06T08:22:28Z",  
  105.                     "capabilityStatus""Deleted",  
  106.                     "service""Sway",  
  107.                     "servicePlanId""a23b959c-7ce8-4e57-9140-b90eb88a9e97"  
  108.                 },  
  109.                 {  
  110.                     "assignedDateTime""2018-09-06T08:22:28Z",  
  111.                     "capabilityStatus""Deleted",  
  112.                     "service""ProjectWorkManagement",  
  113.                     "servicePlanId""b737dad2-2f6c-4c65-90e3-ca563267e8b9"  
  114.                 },  
  115.                 {  
  116.                     "assignedDateTime""2018-09-06T08:22:28Z",  
  117.                     "capabilityStatus""Deleted",  
  118.                     "service""TeamspaceAPI",  
  119.                     "servicePlanId""57ff2da0-773e-42df-b2af-ffb7a2317929"  
  120.                 },  
  121.                 {  
  122.                     "assignedDateTime""2018-09-06T08:22:28Z",  
  123.                     "capabilityStatus""Deleted",  
  124.                     "service""PowerAppsService",  
  125.                     "servicePlanId""c68f8d98-5534-41c8-bf36-22fa496fa792"  
  126.                 },  
  127.                 {  
  128.                     "assignedDateTime""2018-09-06T08:22:28Z",  
  129.                     "capabilityStatus""Deleted",  
  130.                     "service""ProcessSimple",  
  131.                     "servicePlanId""76846ad7-7776-4c40-a281-a386362dd1b9"  
  132.                 },  
  133.                 {  
  134.                     "assignedDateTime""2018-09-06T08:22:28Z",  
  135.                     "capabilityStatus""Deleted",  
  136.                     "service""Deskless",  
  137.                     "servicePlanId""8c7d2df8-86f0-4902-b2ed-a0458298f3b3"  
  138.                 },  
  139.                 {  
  140.                     "assignedDateTime""2018-09-06T08:22:28Z",  
  141.                     "capabilityStatus""Deleted",  
  142.                     "service""MicrosoftStream",  
  143.                     "servicePlanId""9e700747-8b1d-45e5-ab8d-ef187ceec156"  
  144.                 },  
  145.                 {  
  146.                     "assignedDateTime""2018-09-06T08:22:28Z",  
  147.                     "capabilityStatus""Deleted",  
  148.                     "service""OfficeForms",  
  149.                     "servicePlanId""2789c901-c14e-48ab-a76a-be334d9d793a"  
  150.                 },  
  151.                 {  
  152.                     "assignedDateTime""2018-09-06T08:22:28Z",  
  153.                     "capabilityStatus""Deleted",  
  154.                     "service""To-Do",  
  155.                     "servicePlanId""c87f142c-d1e9-4363-8630-aaea9c4d9ae5"  
  156.                 }  
  157.             ],  
  158.             "deviceKeys": [],  
  159.             "onPremisesExtensionAttributes": {  
  160.                 "extensionAttribute1"null,  
  161.                 "extensionAttribute2"null,  
  162.                 "extensionAttribute3"null,  
  163.                 "extensionAttribute4"null,  
  164.                 "extensionAttribute5"null,  
  165.                 "extensionAttribute6"null,  
  166.                 "extensionAttribute7"null,  
  167.                 "extensionAttribute8"null,  
  168.                 "extensionAttribute9"null,  
  169.                 "extensionAttribute10"null,  
  170.                 "extensionAttribute11"null,  
  171.                 "extensionAttribute12"null,  
  172.                 "extensionAttribute13"null,  
  173.                 "extensionAttribute14"null,  
  174.                 "extensionAttribute15"null  
  175.             },  
  176.             "onPremisesProvisioningErrors": [],  
  177.             "provisionedPlans": [  
  178.                 {  
  179.                     "capabilityStatus""Enabled",  
  180.                     "provisioningStatus""Success",  
  181.                     "service""MicrosoftCommunicationsOnline"  
  182.                 },  
  183.                 {  
  184.                     "capabilityStatus""Enabled",  
  185.                     "provisioningStatus""Success",  
  186.                     "service""exchange"  
  187.                 },  
  188.                 {  
  189.                     "capabilityStatus""Enabled",  
  190.                     "provisioningStatus""Success",  
  191.                     "service""SharePoint"  
  192.                 },  
  193.                 {  
  194.                     "capabilityStatus""Enabled",  
  195.                     "provisioningStatus""Success",  
  196.                     "service""SharePoint"  
  197.                 }  
  198.             ]  
  199.         }  

How to verify the results in O365?

Once you get the results, you can verify the results from O365 and also, follow the below listed steps to verify the output.

Step 1

Log into Microsoft 365 Admin Center. Learn more here.

https://admin.microsoft.com/AdminPortal 

Step 2

From Microsoft 365 Admin Center, click Users option and then Active Users option.
 
How To Register An App In Azure Active Directory

Step 3

From Active Users, click any one user’s display name and validate the email address.
 
How To Register An App In Azure Active Directory 

Step 4

Then scroll down the page and select the contact information
 
How To Register An App In Azure Active Directory 

Step 5

From Edit Contact Information, verify the following fields First Name, Last Name, Location, Department.
 
How To Register An App In Azure Active Directory 

And also, you can export the users and validate the details.

Step 6

From Active users, click Export option (select all users and click on export button, and you will get the Excel sheet with all the O365 Users)
 
How To Register An App In Azure Active Directory 

Summary

In this article, we have explored how to get the information of all the users from O365 organization using Graph API. Happy learning.