I am trying to retrieve users orderby createdDateTime, but the Graph API doesn’t seem to like it
This fails with a (400) Bad Request:
https://graph.microsoft.com/beta/users?`$select=displayName,userPrincipalName,mail,id,createdDateTime,signInActivity,userType&`$top=100&`$orderby=createdDateTime desc
Whereas order by displayName works just fine:
https://graph.microsoft.com/beta/users?`$select=displayName,userPrincipalName,mail,id,createdDateTime,signInActivity,userType&`$top=100&`$orderby=displayName desc
My API permissions are fine in that i can see createdDateTime in the results of the secondary query.
If this is not possible via this method, what is the best way to get the last thousand users to sign up?
2
Answers
It’s an advanced query which requires
ConsistencyLevel:eventual
request header and the query parameter$count
set totrue
.I suppose you are trying to make a request from PowerShell and you are escaping $ with `$
There are two classifications of queries which you can make for directory objects using the Geaph API.
Basic queries comprise standard functions, such as
$filter
,$select
,$top
and$orderby
. However, there are a number if scenarios where a query may not be considered basic even when only using these.Advanced queries are deemed to be those which require a more complex approach to building results. This could be for queries which require aggregation, are a distributed transaction (requiring coordination across multiple systems) etc.
As per this table you’ll see that sorting results on
creationDateTime
property for user objects renders your query an advanced query. From your perspective, it shouldn’t matter much whether the query is advanced or basic, but advanced queries require specification of a consistency level.Azure AD relies on a distributed datastore, due the nature of its global presence. With this distributed "database" [loosely defined] there are multiple copies of the same data, which are replicated, even across different continents, in most cases (with exception to government instances).
Behind the scenes, a multi-master replication mechanism ensures that the separate copies of data are kept in alignment with eachother. Multi-master referred to the ability to write to either or any copy and the new or updated data will be replicated to the others.
As of writing, the only published consistency level available in Graph is
eventual
. So, why are we required to specify it if there is only one available option? It is for developers and administrators to indicate their intent, and their awareness that the results provided by the API may not reflect the most up-to-date data across all instances of it. Some of these might be reading this answer now, figuring out the what and the why.Graph will typically query a copy of the data which is [relatively] local to it.
Let’s say you are in the US, and your company has a branch in the UK. An admin in the UK creates a new user. You have an app or a script which queries Graph for the last 100 users created, shortly after. Due to replication latency, it is possible that your query will not return the user created in the UK.
Unless you need to cater for some very niche or specific scenario, you’re unlikely to need to be concerned about this latency. Reports of layency-related issues are not very common.
The
$count=true
query parameter basically instructs the API to include an@odata
object in the response, in case Graph determines that pagination of the results (breaking down the response in to multiple accessible subsets) is deemed appropriate or necessary.Back to how you overcome this
Bad Request (400)
issue. I am assuming based on your inclusion of backticks in your quoted request URIs that you’re using PowerShell, so please see my example below on how to call Graph beta using the required query parameters and ConsistencyLevel header: