azure logo

The Microsoft GraphAPI is a powerful tool to have. Not only can we use it to create tooling to automate our workloads—we can also access new functions earlier.

In this article, we’ll learn how to explore and use the Microsoft GraphAPI for Azure AD.


You must meet a few prerequisites before we can begin. Before you begin with the steps outlined in this article, be sure you meet or have the following:

  • An App Registration in AzureAD with the following GraphAPI permissions:
    • Directory.Read.All
    • Directory.ReadWrite.All
  • Application Id (client-id) and client-secret for above App Registration
  • Your Tenant name
  • A computer running PowerShell version 5.1 or above

With that out of the way—let’s learn how to explore the GraphAPI.

Read the Documentation

The Microsoft GraphAPI is well-documented, and the best place to begin when finding out how to use a new function is to start in the reference documentation of the Microsoft Graph API.

This specifies how to use a specific function and what permissions you need to use it. There are currently two versions of the GraphAPI: v1.0 and the beta API. They may look identical at first, but the beta API contains a lot of new functions that are not yet released. Also be aware that functions in the beta API are subject to change at any time.


Permissions are an important part of exploring and using the Graph API permissions—luckily all the permissions that you need to perform a certain action are specified in the reference documentation of that function.

The following screenshot shows the permission needed to use the getDirectoryObject function. And because you will access it as an application, you need the Directory.ReadAll permission.

You need the Directory.ReadAll permission to use the getDirectoryObject function.

Now that you have the basics, let’s get started by requesting an access token—a temporary secret that we will use to access the Microsoft Graph API.

Requesting an Access Token

The access token is a secret that you can request with our client-id and client-secret. It is this token that you must in the requests towards the GraphAPI.

To request an access token, you need to authorize yourself against the tenant’s oauth2 endpoint by posting your Application Id and Application Secret.

Edit the following script, replacing AppId, AppSecret, and Tenant name, and run it in PowerShell to request an access token:

Add-Type -AssemblyName System.Web

$AppSecret = 'CHANGEME'
$Scope = ""
$TenantName = ""

$Url = "$TenantName/oauth2/v2.0/token"

$Body = @{
  client_id = $AppId
	client_secret = $AppSecret
	scope = $Scope
	grant_type = 'client_credentials'

$PostSplat = @{
    ContentType = 'application/x-www-form-urlencoded'
    Method = 'POST'
    Body = $Body
    Uri = $Url

# Request the token!
$Request = Invoke-RestMethod @PostSplat

Now if you take a look at the $Request variable, you can see that it contains our access token, as well as type and expiration time.

PS51> $Request

token_type expires_in ext_expires_in access_token                                                                                                      
---------- ---------- -------------- ------------                                                                                                      
Bearer           3599           3599 eyJ...............

The expires_in is in seconds, which means that you have to request a new token within an hour or it will stop working.

Let us save the access token in a variable for future use and then start making requests towards the GraphApi:

PS51> $AccessToken = $Request.access_token

Your First GraphAPI Request

It is time for your first graph request! The simplest requests to start with are the requests that utilizes HTTP GET. The GET commands are only for fetching information, so you don’t need to worry about messing anything up.

We will start out with a simple request listing the domains tied to our tenant. And remember—read the documentation. All information on how to use the GraphAPI functions is in the documentation.

You might have noticed in the documentation for the List Domains command that you can call it by using HTTP GET—the default method when using Invoke-RestMethod:

You can call a List Domains command using HTTP GET.

With this information, you can start constructing the request. For that, we need to create an Authorization Header that contains “Bearer <token>” and use that to make a GET request towards the URL in the picture above:

$Headers = @{
    Authorization = "Bearer $AccessToken"

$Uri = ""

$Result = Invoke-RestMethod -Headers $Headers -Uri $Uri

You now have the list of domains in the $Result variable, but trying to output the value of the $Result variable will result in this:

PS51> $Result

@odata.context                                     value                                                                                               
--------------                                     -----                                                                                               
<$metadata#domains> {@{authenticationType=Managed; availabilityStatus=;; isAdminManaged=True; isD..

The result of the query is usually in the value property of the result. You can get the whole result by just outputting that property instead:

PS51> $Result.value

authenticationType               : Managed
availabilityStatus               : 
id                               :
isAdminManaged                   : True
isDefault                        : True
isInitial                        : False
isRoot                           : True
isVerified                       : True
supportedServices                : {Email, Intune}
state                            : 
passwordValidityPeriodInDays     : 2147483647
passwordNotificationWindowInDays : 14

authenticationType               : Managed
availabilityStatus               : 
id                               :
isAdminManaged                   : True
isDefault                        : False
isInitial                        : True
isRoot                           : True
isVerified                       : True
supportedServices                : {Email, OfficeCommunicationsOnline}
state                            : 
passwordValidityPeriodInDays     : 2147483647
passwordNotificationWindowInDays : 14

Now that you’ve learned the basics of getting information with the GraphAPI, it’s time to learn how to use filters.

Using Filters

It is great to be able to fetch all data that are available. And while it may work, it is awfully ineffective. A good practice is to only request the data that you need. To achieve this in the GraphAPI, we can use filters.

A good candidate for trying out filters is by fetching users. They have a lot of common attribute names to on-prem Active Directory, and you usually have at least a few of them.

The URI for fetching all users is **, but we want to filter this request. You can do that by adding the $filter=<filter> parameter to the URI.

A filter (usually) consists of property operator and a value like this:

property operator 'value'

If you now want to fetch all users with the givenName “John,” the following URI should be used:$filter=givenName eq 'John'

So, if you want to use PowerShell to make this request, the code should look something like this:

$Uri = "`$filter=givenName eq 'John'"
$Result = Invoke-RestMethod -Headers $Headers -Uri $Uri

Notice the backtick before $filter—that’s to escape the dollar sign—else PowerShell would’ve interpreted it as a variable.

Take a look at the value property,  and you will see all users with a givenName of “John” in Azure Active Directory:

PS51> $Result.value

businessPhones    : {5554012}
displayName       : John Doe
givenName         : John
jobTitle          : 
mail              :
mobilePhone       : 
officeLocation    : 
preferredLanguage : en
surname           : Doe
userPrincipalName :
id                : 7fd22087-ec0a-47a1-91fb-0a7d8e6f0c

‘EQ’ is not the only operator, you have not (ne), match, contains, less/greater than (lt/gt), and a whole lot more. While out of the scope of this article, more information about operators is available in the documentation. Also more extensive documentation about the different filter properties is available in the property documentation about each object type.

Creating a User

Now that you got the basics, let’s perform a write operation and create a user. For that, you need to know how to construct the data and where to POST it. You can see an example on how to perform that by going to the Microsoft Graph API documentation and looking at “Create User”:

Perform a write operation and create a user.

You can see that you need to send the data as a POST request, and that the content type should be of application/json. You can also see a JSON representation of the data—the goal here is to create a PowerShell object that creates that JSON when ConvertTo-Json is used on it.

Let’s have a go at it:

$Body = [PSCustomObject]@{
    accountEnabled = $True
    displayName = "Jane Doe"
    mailNickname = "janedoe"
    userPrincipalName = ""
    passwordProfile = @{
        forceChangePasswordNextSignIn = $True
        password = "Hunter221!"

Running $Body | ConvertTo-Json will result in a similar JSON as the one displayed in the documentation. What’s left now is to convert it to JSON and POST it to the GraphAPI URI with the right content-type:

$Body = [PSCustomObject]@{
    accountEnabled = $True
    displayName = "Jane Doe"
    mailNickname = "janedoe"
    userPrincipalName = ""
    passwordProfile = @{
        forceChangePasswordNextSignIn = $True
        password = "Hunter221!"

$BodyJson = $Body | ConvertTo-Json
$Uri = ""

Invoke-RestMethod -Uri $Uri -Headers $Headers -Method POST -ContentType application/json -Body $BodyJson

If you now go to our Azure Active Directory Console and have a look, you will find the newly created user:

The newly created user in the Azure Active Directory Console.

You have now created your first user using GraphAPI!


The Microsoft GraphAPI is a powerful tool and will enable you to automate your environment even further. And not just when it comes to Azure Active Directory—but also for the majority of SaaS services that Microsoft offers.

Also considering the “serverless” movement using Azure Functions or AWS Lambda in an event, it’s possible to create minimalistic and event-driven functions to automate as much as possible in your environment. All without the need to include large libraries into your functions.

Profile Photo for Adam Bertram Adam Bertram
Adam Bertram is a 20+ year veteran of IT and an experienced online business professional. He’s a consultant, Microsoft MVP, blogger, trainer, published author and content marketer for multiple technology companies.
Read Full Bio »