Working with Azure Active Directory Graph Api from Powershell
Hello Everyone,
In this blog post I'm going to show a simple way to work with Azure Active Directory Graph Api directly from Powershell.
Basically in order to access this API we first need to be authenticated with ADAL (Active Directory Authentication Library), this authentication will is done trough a JSON formatted token that is then passed as a parameter in the header for the Invoke-RestMethod cmdlet.
This blog post assumes you already have Azure Powershell 1.0 or greater module installed in your computer, if not, you can install it from https://aka.ms/webpi-azps.
We don’t intend here to build a full featured script but at least provide a function to get the Authentication Token and show a few examples using Graph Api calls. For a similar article but based on REST API, Azure Management and a Sample Script to identify page blob status (like if a VHD is attached or not to a VM), please refer to Working with Azure REST APIs from Powershell – Getting page and block blob information from ARM based storage account sample script blog post.
To get started, open a Powershell command prompt and type (or paste) the following code, this will create a function in your session that will be able to return the Authentication token:
To use this function just type:
$token = GetAuthToken -TenantName "<your Azure AD tenant>.onmicrosoft.com"
For example:
$token = GetAuthToken -TenantName "pmcazureme1.onmicrosoft.com"
Getting back to the example, lets define some variables so we can avoid lots of typing:
# Defining Azure AD tenant name, this is the name of your Azure Active Directory (do not use the verified domain name)
$tenant = ”pmcazureme1.onmicrosoft.com”
# Getting the authorization token
$token = GetAuthToken -TenantName $tenant
# Building Rest Api header with authorization token
$authHeader = @{
'Content-Type'='application\json'
'Authorization'=$token.CreateAuthorizationHeader()
}
With these variables and results obtained from GetAuthToken function we built the foundation to start executing calls to Graph Api, this Api has the following format:
Each block of code now will perform a different task using Graph Api:
Getting tenant information
$resource = "tenantDetails"
$uri = "https://graph.windows.net/$tenant/$($resource)?api-version=1.6"
$tenantInfo = (Invoke-RestMethod -Uri $uri –Headers $authHeader –Method Get –Verbose).value
Result
Getting a list of all users
$resource = "users"
$uri = "https://graph.windows.net/$tenant/$($resource)?api-version=1.6"
$users = (Invoke-RestMethod -Uri $uri –Headers $authHeader –Method Get –Verbose).value
Result
Getting a list of users that Display Name starts with letter T by using OData filtering
$resource = "users"
$uri = "https://graph.windows.net/$tenant/$($resource)?api-version=1.6`&`$filter=startswith(displayName,'T')"
$users = (Invoke-RestMethod -Uri $uri –Headers $authHeader –Method Get –Verbose).value
Result
Getting a list of groups
$resource = "groups"
$uri = "https://graph.windows.net/$tenant/$($resource)?api-version=1.6"
$groups = (Invoke-RestMethod -Uri $uri –Headers $authHeader –Method Get –Verbose).value
Result
So far we only did read operations, what about creating a real user on Azure AD by using the graph API?
First, lets define our user properties in a Powershell hash table, in this way we can easily convert it to JSON format and send as the body content of the Graph Api Post method.
$newuser = @{
"accountEnabled"=$true;
"userPrincipalName"="pmc@pmcazureme1.onmicrosoft.com";
"displayName"="Paulo Marques";
"passwordProfile"=@{
"password"="adHDla@#sdj";`
"forceChangePasswordNextLogin"=$true
};
"mailNickname"="pmc"
}
To see your hash table, just type $newuser and press enter:
Last step before jumping in the Invoke-RestMethod is converting this hash table into a JSON structure, type the following line and press enter:
$newuserJsonDef = $newuser | ConvertTo-Json
To see the newly converted object, just type $newuserJsonDef and press enter:
Lets build again our $uri variable:
$resource = "users"
$uri = "https://graph.windows.net/$tenant/$($resource)?api-version=1.6"
Run the Invoke-RestMethod cmdlet to get your user created on Azure Active Directory, notice the new parameters and values highlighted:
$result = Invoke-RestMethod -Uri $uri -Headers $authHeader -Method Post -Body $newuserJsonDef -ContentType "application/json"
Check the result by querying your new user:
$uri = "https://graph.windows.net/$tenant/users`?api-version=1.6`&`$filter=mailNickname eq 'pmc'"
(Invoke-RestMethod -Uri $uri –Headers $authHeader –Method Get –Verbose).value
For more information about Graph Api, please refer to the following articles:
Operations overview | Graph API concepts
https://msdn.microsoft.com/library/azure/ad/graph/howto/azure-ad-graph-api-operations-overview
Azure AD Graph API reference
https://msdn.microsoft.com/library/azure/ad/graph/api/api-catalog
Versioning | Graph API concepts
https://msdn.microsoft.com/library/azure/ad/graph/howto/azure-ad-graph-api-versioning
Supported queries, filters, and paging options | Graph API concepts
https://msdn.microsoft.com/library/azure/ad/graph/howto/azure-ad-graph-api-supported-queries-filters-and-paging-options
That’s it for this blog post, see you later!
Comments
- Anonymous
July 09, 2016
Minor uri variable correction:$uri = "https://graph.windows.net/$tenant/$($resource)?api-version=1.6"- Anonymous
August 02, 2016
Hi UNIFYBob,The way the example also works, the issue that I was seeing is that when I pasted the code from Word it changed some of the characters and that's why a direct copy and paste on PowerShell command prompt window was not working, I changed all the examples with your recommendation because it looks nicer that the original one and I also changed the way the examples are included in this post to follow all other subsequent posts that I had.Thanks for your comment.RegardsPaulo
- Anonymous
- Anonymous
August 16, 2016
Is there any way to automate the authentication process in a manner similar to the Connect-MsolService -Credential option?For example, if creds are stored in a variable $cred, then the following will authenticate without any prompts:Connect-MsolService -Credential $credCheers, Ian- Anonymous
September 08, 2016
Yes. You can visit my blog for that variation. I will post that this week sometime. Thanks.
- Anonymous
- Anonymous
September 29, 2016
At the start of your post you probably should tell users to create an app in Azure AD first, from which they'll get the client id and redirect URI that you use in the GetAuthToken method.- Anonymous
November 01, 2016
Hi Irwin, the application ID in this case is PowerShell so this is not needed, it is already built in on Azure AD.
- Anonymous
- Anonymous
November 15, 2016
How do i download the DLLs referenced?- Anonymous
January 06, 2017
Hi Max,This DLL is part of the Azure PowerShell module which is the only requirement for this to work, as I mentioned in the blog, you can install it from https://aka.ms/webpi-azps URL.RegardsPaulo
- Anonymous
- Anonymous
February 22, 2017
the function requires to authenticate with an user action.$authContext.AcquireToken($resourceAppIdURI,$clientId,$redirectUri, "auto")Is there a way to use a encrypted password xml file that I can use the function within script that runs on a schedule ?$CredPath = "$home\Desktop\mycred.xml"Get-Credential | Export-Clixml -Path $CredPath- Anonymous
February 22, 2017
Hi Matthias,The most secure way is to work with Azure Key Vault (https://azure.microsoft.com/en-us/services/key-vault), I put together below the list of documents and blog posts that will help you to securely authenticate:1) Create an Azure AD Service Principal and optionally assign what role that user will have.Using a Service Principal for Azure PowerShell Authenticationhttps://blogs.msdn.microsoft.com/cloud_solution_architect/2015/05/14/using-a-service-principal-for-azure-powershell-authentication2) Next, you can use my blog post on how to setup Azure Key vault and how to use it from PowerShell so you can securely retrieve the password (secret) you placed there.Safeguarding your passwords when deploying Azure Virtual Machines with Azure PowerShell module and ARM Templates by using Azure Key Vaulthttps://blogs.technet.microsoft.com/paulomarques/2016/05/27/safeguarding-your-passwords-when-deploying-azure-virtual-machines-with-azure-powershell-module-and-arm-templates-by-using-azure-key-vault3) Finally, the last step would be assigning a policy that allows the Service Principal to retrieve the secret from Key Vault, the steps are outlined at the Authorize the application to use the key or secret section.Get started with Azure Key Vaulthttps://docs.microsoft.com/en-us/azure/key-vault/key-vault-get-startedI didn't test this but I believe it is a good start to automate an end to end scenario.Hope that helps.RegardsPaulo- Anonymous
February 27, 2017
thanks - I will give it a try
- Anonymous
- Anonymous
- Anonymous
May 09, 2017
I am getting an error any ideas?Invoke-RestMethod : The 'Content-Type' header must be modified using the appropriate property or method.PS C:\ps> $authHeaderName Value---- -----Authorization Bearer ########Content-Type application\json- Anonymous
May 11, 2017
Hi Flaphead, can you add all the command lines you're using until you get the error?
- Anonymous