Filter on onPremisesExtensionAttributes - c#

Iam trying to make Make a GET request to the /users endpoint, using the filter parameter to specify the onPremisesExtensionAttributes value:
var users = await graphClient.Users
.Request()
.Filter($"onPremisesExtensionAttributes/{extensionAttributeName} eq '{extensionAttributeValue}'")
.GetAsync();
but i got error "Microsoft.Graph.ServiceException: 'Code: Request_UnsupportedQuery
Message: Unsupported or invalid query filter clause specified for property 'extensionAttribute14' of resource 'User'."
i can get the uers onPremisesExtensionAttributes values and
filter works fine with other parameters like department of givenName but only show error with onPremisesExtensionAttributes
I had searched alot abut this problem and advanced querties for azure Ad on "https://learn.microsoft.com/en-us/graph/aad-advanced-queries?tabs=csharp"

To make it work you need to add query parameter $count with value true and the header ConsistencyLevel:eventual
List<Option> requestOptions = new List<Option>();
requestOptions.Add(new QueryOption("$count", "true"));
requestOptions.Add(new HeaderOption("ConsistencyLevel", "eventual"));
var users = await graphClient.Users
.Request(requestOptions)
.Filter($"onPremisesExtensionAttributes/{extensionAttributeName} eq '{extensionAttributeValue}'")
.GetAsync();

Related

How to filter Email Messages by Subject Body & HasAttachments using C# Graph API

var inboxMessages = await graphClient.Me
.MailFolders["Inbox"]
.Messages
.Request()
.Select("sender,subject")
.Top(5)
.GetAsync();
I want to filter the messages by subject and hasAttachment using C#
I am seeing few examples like this ,but how we need implement this in C# in above code?
/v1.0/me/messages?$search="subject:search term"
/v1.0/me/messages?$filter=contains(subject, 'my search term')
Can anyone help me out on this.
You can filter messages with attachments based on the subject that contains specific text like this
var subjectText = "your text";
var inboxMessages = await graphClient.Me
.MailFolders["Inbox"]
.Messages
.Request()
.Select("sender,subject")
.Filter($"hasAttachments eq true and contains(subject,'{subjectText}')")
.Top(5)
.GetAsync();
Documentation:
$filter query operator

Include search in Microsoft graph query C#

How do I run the query
https://graph.microsoft.com/v1.0/users?$count=true&$search="displayName:room"&$filter=endsWith(mail,'xxxx.com')&$select=id,displayName,mail
in C#?
this is what I have now:
return await _graphServiceClient
.Users.Request()
.Header("ConsistencyLevel", "eventual")
. .Filter($"(endsWith(mail, 'xxxx.com'))&$count=true")
.Select("id,displayName,mail")
.Top(999)
.GetAsync();
Try this code pls:
var queryOptions = new List<QueryOption>()
{
new QueryOption("$count", "true"),
new QueryOption("$search", "\"displayName:tiny\"")
};
var res = await graphClient
.Users.Request(queryOptions)
.Header("ConsistencyLevel", "eventual")
.Filter("endswith(mail,'contoso.com')")
.OrderBy("userPrincipalName")
.Select("id,displayName,mail")
.Top(999)
.GetAsync();
When we follow the official code snippet, we should use .Search() but it will meet exception:
Then let's see github issue here, and we can set search parameter into query option.

Microsoft Graph Get All Users Exception Unsupported Query

I can submit this query to Microsoft Graph Explorer but in C# I get the an error message: "Microsoft.Graph.ServiceException: "Code: Request_UnsupportedQuery
Message: Unsupported Query."
var users = await graphClient.Users
.Request()
.Filter("endswith(mail,'#mydomain.com')")
.OrderBy("userPrincipalName")
.GetAsync();
You should send a header ConsistencyLevel=eventual and also $count query parameter to make it work.
To add $count query parameter you can use queryOptions.
List<QueryOption> queryOptions = new List<QueryOption>
{
new QueryOption("$count", true)
};
var users = await graphClient.Users
.Request(queryOptions)
.Filter("endswith(mail,'#mydomain.com')")
.OrderBy("userPrincipalName")
.GetAsync();
The API call what look something like this
https://graph.microsoft.com/v1.0/users?$count=true&$filter=endswith(mail, '#domain.live')&$orderBy=userPrincipalName
You can always test these calls in Graph Explorer.

QueryOptions ignored when getting calendar events in MSGraph Dot Net

I'm trying to get the user's calendar events for today. So I added some query parameters but they're getting ignored and the graph client returns the user's events as if I didn't supply any parameters (startatetime):
var options = new QueryOption[]
{
new QueryOption("startdatetime", DateTime.UtcNow.ToString("o")),
new QueryOption("enddatetime", DateTime.UtcNow.AddDays(1).ToString("o")),
};
var events = await graphServiceClient
.Me
.Calendar
.Events
.Request(options)
.GetAsync();
I tested it in the graph explorer and it works fine. But in the sdk, it returns calendar events that started before today.
Your code is the equivalent of calling:
`/events?startdatetime={dateTime}&enddatetime={dateTime}`.
That is a valid endpoint, but you're passing invalid query params. What you're looking for is calendarView:
`/calendarView?startdatetime={dateTime}&enddatetime={dateTime}`
Using the SDK, this would look like this:
var options = new QueryOption[]
{
new QueryOption("startDateTime", DateTime.UtcNow.ToString("o")),
new QueryOption("endDateTime", DateTime.UtcNow.AddDays(1).ToString("o")),
};
var events = await graphServiceClient
.Me
.CalendarView
.Request(options)
.GetAsync();

How to get user id from email address in Microsoft Graph API C#

I want to add User to a Group but I don't have the User's id, I only have the email address.
Here is the code:
User userToAdd = await graphClient
.Users["objectID"]
.Request()
.GetAsync();
await graphClient
.Groups["groupObjectID"]
.Members
.References
.Request()
.AddAsync(userToAdd);
Can someone help how do I retrieve ObjectId (User ID) from an email address using Microsoft Graph?
You can look up a user a few different ways.
From the /users endpoint you can either use their id (the GUID assigned to each account) or their userPrincipalName (their email alias for the default domain):
// Retrieve a user by id
var user = await graphClient
.Users["00000000-0000-0000-0000-000000000000"]
.Request()
.GetAsync();
// Retrieve a user by userPrincipalName
var user = await graphClient
.Users["user#tenant.onmicrosoft.com"]
.Request()
.GetAsync();
If you're using either the Authorization Code or Implicit OAuth grants, you can also look up the user who authenticated via the /me endpoint:
var user = await graphClient
.Me
.Request()
.GetAsync();
Besides these correct answers above.
userPrincipalName or id is not the external email address. That was my case when registration is done manually. You can use this filter:
var user = await _graphClient.Users
.Request()
.Filter($"identities/any(c:c/issuerAssignedId eq '{email}' and c/issuer eq 'contoso.onmicrosoft.com')")
.GetAsync();
src: https://learn.microsoft.com/en-us/graph/api/user-list?view=graph-rest-1.0&tabs=csharp
Using this configuration to create an user:
Microsoft.Graph.User graphUser = new Microsoft.Graph.User
{
AccountEnabled = true,
PasswordPolicies = "DisablePasswordExpiration,DisableStrongPassword",
PasswordProfile = new PasswordProfile
{
ForceChangePasswordNextSignIn = false,
Password = accountModel.Password,
},
Identities = new List<ObjectIdentity>
{
new ObjectIdentity()
{
SignInType = "emailAddress",
Issuer ="contoso.onmicrosoft.com",
IssuerAssignedId = email
}
},
};
You can retrieve user's details from Graph API using id or userPrincipalName (which is an email address).
From Microsoft Graph API reference:
GET /users/{id | userPrincipalName}
Have you tried to use the email address as objectID?
If you need retrieve a guest user may use:
public static async Task<User> GetGuestUserByEmail(string email)
{
try
{
var request = await graphClient
.Users
.Request()
.Filter($"userType eq 'guest' and mail eq '{email}'") // apply filter
.GetAsync();
var guestUsers = request.CurrentPage.ToList();
var user = guestUsers.FirstOrDefault();
return user;
}
catch (ServiceException ex)
{
Console.WriteLine($"Error: {ex.Message}");
return null;
}
}
There actually is no truly reliable way to do this. Email addresses in AAD are not unique. The UPN is often an email address, and it is unique, but there's a nasty catch: If the person happens to have a long email address AND they're a guest user, the UPN appears to be the email truncated to 54 characters, then have #EXT# tacked on, and it can even be changed after the fact to have the #EXT# removed where it can be up to 64 characters before the # symbol, and doesn't have to be anything resembling their actual email address.
The only way you're supposed to actually be able to find them is with their user object's GUID.
https://learn.microsoft.com/en-us/answers/questions/81053/user-principal-name-and-ext.html
There is a reliable way to get the emails address using the Open ID mechanism. With openid as a scope, you can get the userinfo_endpoint endpoint from https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration
GET https://graph.microsoft.com/oidc/userinfo (this endpoint shouldn't be hard coded)
{
"sub": "uniqueid",
"name": "Name",
"family_name": "Name",
"given_name": "Name",
"picture": "https://graph.microsoft.com/v1.0/me/photo/$value",
"email": "email#example.com"
}
https://learn.microsoft.com/en-us/azure/active-directory/develop/userinfo
Such a seemingly simple thing and yet so complex. My strategy:
var users = await graphClient.Users.Request()
.Filter($"userPrincipalName eq '{targetEmail}' or mail eq '{targetEmail}'")
.GetAsync();
If all you have is the email address you can't get around the possibility of more than one hit and letting your user pick the right one. Which makes sense, since if you're ever adding people to something in the Azure portal or DevOps it's the same thing.
But at least this way you should have both your internal users (via userPrincipalName) and guests (via mail) covered in one query.

Categories