I have a code in C# that takes some user information (displayname, jobtitle and department) and also needs the manager's displayname, but I don't know how to get the displayname inside the Manager object inside the User query. How can I do this?
var userorg = await graphClient.Users
.Request()
.Select("AccountEnabled,displayName,Department,JobTitle,Manager")
.Top(999)
.GetAsync();
foreach (var user in userorg)
{
if (user.AccountEnabled == true)
{
Console.WriteLine(user.DisplayName);
Console.WriteLine(user.Department);
Console.WriteLine(user.JobTitle);
}
}
Thanks
Edit: I created a new solution because the old one was VERY old and very dirty. Using the code as a base, I recreated what I needed and it works well, but it only displays the first 100, even including Top = 999. It only makes a difference if I put the TOP below 100, but above that it is ignored. In the old code, TOP 999 worked.
Edit2: I managed to solve the problem using odata.nextlink, I just don't know if it was the best way, the important thing is that it works!
var csv = new StringBuilder();
var scopes = new[] { "https://graph.microsoft.com/.default" };
var clientId = "xxxx";
var tenantId = "xxxxx";
var clientSecret = "xxxxxx";
var options = new ClientSecretCredentialOptions
{
AuthorityHost = AzureAuthorityHosts.AzurePublicCloud,
};
var clientSecretCredential = new ClientSecretCredential(
tenantId, clientId, clientSecret, options);
var graphClient = new GraphServiceClient(clientSecretCredential, scopes);
int i = 0;
string sToken = null;
try
{
while (i == 0 || sToken != null)
{
if (i == 0)
{
var users = await graphClient.Users.GetAsync((requestConfiguration) =>
{
requestConfiguration.QueryParameters.Expand = new string[] { "manager($select=displayName,id)" };
requestConfiguration.QueryParameters.Select = new string[]
{ "accountEnabled", "displayName", "UserPrincipalName", "department", "jobTitle", "manager" };
});
foreach (var user in users.Value)
{
if (user.AccountEnabled == true && user.UserPrincipalName.Contains("crebti.onmicrosoft.com") != true
&& user.UserPrincipalName.Contains("#EXT") != true)
{
string f = user.DisplayName;
string s = user.Department;
string t = user.JobTitle;
string q = null;
if (user.Manager != null)
{
var manager = await graphClient.Users[user.Manager.Id].GetAsync((requestConfiguration) =>
{
requestConfiguration.QueryParameters.Select = new string[] { "displayName" };
});
q = manager.DisplayName;
}
var nL = $"{f},{s},{t},{q}";
csv.AppendLine(nL);
}
}
if (users.OdataNextLink != null)
{
sToken = users.OdataNextLink;
string tokin = "$skiptoken=";
sToken = sToken.Substring(sToken.IndexOf(tokin) + tokin.Length);
}
i++;
}
else
{
string delta = "https://graph.microsoft.com/v1.0/users?$expand=manager($select=displayName,id),&$select=accountEnabled,displayName,UserPrincipalName,department,jobTitle,manager,&$skiptoken=" + sToken;
var result = new Microsoft.Graph.Users.Delta.DeltaRequestBuilder(delta, graphClient.RequestAdapter);
var users = await result.GetAsync();
foreach (var user in users.Value)
{
if (user.AccountEnabled == true && user.UserPrincipalName.Contains("crebti.onmicrosoft.com") != true
&& user.UserPrincipalName.Contains("#EXT") != true)
{
string f = user.DisplayName;
string s = user.Department;
string t = user.JobTitle;
string q = null;
if (user.Manager != null)
{
var manager = await graphClient.Users[user.Manager.Id].GetAsync((requestConfiguration) =>
{
requestConfiguration.QueryParameters.Select = new string[] { "displayName" };
});
q = manager.DisplayName;
}
var nL = $"{f},{s},{t},{q}";
csv.AppendLine(nL);
}
}
if (users.OdataNextLink != null)
{
sToken = users.OdataNextLink;
string tokin = "$skiptoken=";
sToken = sToken.Substring(sToken.IndexOf(tokin) + tokin.Length);
//pipipopopo
}
else sToken = null;
}
}
File.WriteAllText("Auditoria.csv", csv.ToString(), Encoding.UTF8);
}
catch (ODataError odataError)
{
MessageBox.Show(odataError.Error.Message, odataError.Error.Code);
}
You need to use
$expand
in your graph query to get manager details along with user information.
When I ran below query by including $expand
in Graph Explorer, I got the response like this:
GET https://graph.microsoft.com/v1.0/users?$expand=manager($select=displayName),&$select=displayName,department,jobTitle,manager
Response:
To get the same results using c#, I ran below code and got user's information along with manager's name successfully like this:
using Azure.Identity;
using Microsoft.Graph;
using Microsoft.Graph.Models;
using Microsoft.Kiota.Abstractions;
using Microsoft.Graph.Models.ODataErrors;
using System;
var scopes = new[] { "https://graph.microsoft.com/.default" };
var clientId = "appId";
var tenantId = "tenantId";
var clientSecret = "secret";
var options = new ClientSecretCredentialOptions
{
AuthorityHost = AzureAuthorityHosts.AzurePublicCloud,
};
var clientSecretCredential = new ClientSecretCredential(
tenantId, clientId, clientSecret, options);
var graphClient = new GraphServiceClient(clientSecretCredential, scopes);
try
{
var users = await graphClient.Users.GetAsync((requestConfiguration) =>
{
requestConfiguration.QueryParameters.Expand = new string[] { "manager($select=displayName,id)" };
requestConfiguration.QueryParameters.Select = new string[] { "accountEnabled", "displayName", "department", "jobTitle", "manager" };
});
foreach (var user in users.Value)
{
Console.WriteLine($"Name: {user.DisplayName}");
Console.WriteLine($"Job Title: {user.JobTitle}");
Console.WriteLine($"Department: {user.Department}");
if (user.Manager != null)
{
var manager = await graphClient.Users[user.Manager.Id].GetAsync((requestConfiguration) =>
{
requestConfiguration.QueryParameters.Select = new string[] { "displayName" };
});
Console.WriteLine($"Manager: {manager.DisplayName}");
}
Console.WriteLine("------------------------");
}
}
catch (ODataError odataError)
{
Console.WriteLine(odataError.Error.Code);
Console.WriteLine(odataError.Error.Message);
}
Response: