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 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=" + config values.clientId + "&scope=" + config values.scope + "&client_secret=" + config values.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 a sample (it won't work).
{
"scope": "https%3A%2F%2Fgraph.microsoft.com%2F.default",
"tenantId": "7aa111ae-1ab6-4256-af4c-a0c1cdb4575d",
"clientId": "bff7fae8-c253-37e5-9b6a-e096bed54f11",
"clientSecretId": "XgfrmWfX0K/N7SRouCdAskTKrz0cnKN2rS12IkJ9SJk="
}
Step 3. Refer to that config file in your js file, as shown below.
var request = require('sync-request');
var fs = require('fs');
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.
var graphAccessUrl = "https://login.microsoftonline.com/" + configValues.tenantId + "/oauth2/v2.0/token";
var graphTokenBody = "client_id=" + configValues.clientId + "&scope=" + configValues.scope + "&client_secret=" + configValues.clientSecretId + "&grant_type=client_credentials";
Step 5. Get the Authorized token using the below method.
var contentType = "application/x-www-form-urlencoded; charset=utf-8";
var graphTokenError = "Failed to get graph token";
var graphToken = "";
// Call the get token method
getToken(graphAccessUrl, contentType, graphTokenBody, graphTokenError);
// This method is using to get the token from the graph token url and body
function getToken(url, type, content, errorMessage, callback) {
var options = {
'headers':
{
'Content-Type': type
},
'body': content
};
// Posting access parameters to the server
var tokenResponse = httpPost(url, options);
if (tokenResponse.statusCode === 200) {
error = errorMessage;
if (errorMessage === graphTokenError) {
var token = JSON.parse(tokenResponse.body.toString('utf-8'));
graphToken = token.access_token;
}
if (callback) {
return callback();
}
} else {
console.log(errorMessage);
}
}
Step 6. Once you receive 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.
var nextLink = "@odata.nextLink";

reqUrl = "https://graph.microsoft.com/V1.0/users?$top=999";
// Call the get users method after you received the token in mail function
function getUsers(reqUrl) {
try {
var userList = [];
console.log(MESSAGE + "Inside get users data method!!!");
// While condition is added to get more than 1000 users
while (reqUrl) {
var usersResponse = httpGet(reqUrl, graphToken);
if (usersResponse.statusCode == 200) {
failIndex = 0;
var responseBlob = JSON.parse(usersResponse.body.toString('utf-8'));
var parsedJsonres = responseBlob.value;
userList = parsedJsonres;
// add use case value to user collection [array]
for (var i = 0; i < parsedJsonres.length; i++) {
var currItem = parsedJsonres[i];
if (currItem) {
bindUsers(currItem);
}
}
// check whether the next link is available if so we have another set of users
if (responseBlob[nextLink]) {
reqUrl = responseBlob[nextLink];
continue;
} else {
console.log(MESSAGE + "There is no next page..");
break;
}
} else {
if (usersResponse.statusCode === 401 && JSON.parse(usersResponse.body.toString('utf-8'))["error"]["message"] === "Access token has expired.") {
getToken(graphAccessUrl, contentType, graphTokenBody, graphTokenError);
userList = userDetails.concat(getUsers(responseBlob[nextLink]));
} else {
failIndex++;
if (failIndex == retryCount) {
console.log(errorMessage + "User API Call has been failed..");
failIndex = 0;
} else
userList = userDetails.concat(getUsers(responseBlob[nextLink]));
}
}
}
} catch (ex) {
console.log(EXCEPTION_MESSAGE + ex);
}
return userList;
}
// Http method
function httpGet(url, bearerToken) {
var request = require('sync-request');
var res = request('GET', url, {
'headers': {
'Authorization': 'Bearer ' + bearerToken,
'Accept': "application/json"
}
});
return res;
}







Sarathlal SaseendranPosted Dec 7, 2018, 4:26 AM
Good article Kaviya. Keep posting
Naresh SinghalPosted Dec 7, 2018, 12:19 AM
Nice article Kaviya Balasubramanian , Keep it up ...