Created
April 14, 2021 16:59
-
-
Save JustinGrote/3929dbc67e84a6c95f53e34a2dd17ac0 to your computer and use it in GitHub Desktop.
Azure Function Powershell to fetch users from a customer tenant via Microsoft Graph
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using namespace System.Net | |
# Input bindings are passed in via param block. | |
[CmdletBinding()] | |
param( | |
[HttpRequestContext]$Request, | |
[HashTable]$TriggerMetadata | |
) | |
$ErrorActionPreference = 'Stop' | |
#PropertiesToReturn | |
$userProperties = @( | |
'UserPrincipalName' | |
'GivenName' | |
'SurName' | |
'DisplayName' | |
'Mail' | |
'OfficeLocation' | |
'StreetAddress' | |
'City' | |
'State' | |
'PostalCode' | |
'JobTitle' | |
'Department' | |
'BusinessPhones' | |
'MobilePhone' | |
'UserType' | |
'EmployeeId' | |
) | |
function Get-MgAccessToken { | |
[CmdletBinding()] | |
param( | |
$tenantId = $ENV:TENANTID, | |
$appId = $ENV:APPID, | |
$appSecret = $ENV:APPSECRET | |
) | |
$getTokenParams = @{ | |
Uri = "https://login.microsoftonline.com/$tenantId/oauth2/v2.0/token" | |
Method = 'POST' | |
Body = @{ | |
Grant_Type = 'client_credentials' | |
Scope = 'https://graph.microsoft.com/.default' | |
Client_Id = $ENV:APPID | |
Client_Secret = $ENV:APPSECRET | |
} | |
} | |
(Invoke-RestMethod @getTokenParams -ErrorAction Stop).access_token | |
} | |
try { | |
$customer = $TriggerMetaData.customer | |
$filter = $TriggerMetaData.filter | |
if (-not $customer) { | |
throw 'You must specify a customer domain either as a guid or a domain. Example: /api/GetAzureAdUsersForAditaas?customer=adslt.onmicrosoft.com' | |
} | |
$connectResult = Connect-MgGraph -AccessToken (Get-MgAccessToken -Verbose -TenantId $customer) | |
if ($connectResult -ne 'Welcome To Microsoft Graph!') { | |
throw "Could not connect to Microsoft Graph: $PSItem" | |
} | |
$getMgUserParams = @{ | |
Property = $userProperties | |
PageSize = 999 | |
All = $true | |
ErrorAction = 'Stop' | |
} | |
if ($filter) { | |
$getMGUserParams.Filter = $filter | |
$getMgUserParams.ConsistencyLevel = 'Eventual' | |
} | |
$userResult = Get-MgUser @getMgUserParams | |
| Select-Object -Property $userProperties | |
# Associate values to output bindings by calling 'Push-OutputBinding'. | |
Write-Verbose "$($userResult.count) users returned for tenant $customer" | |
Push-OutputBinding -Name Response -Value ( | |
[HttpResponseContext]@{ | |
StatusCode = [HttpStatusCode]::OK | |
Body = $userResult | |
} | |
) | |
} catch { | |
if ([String]$PSItem -match 'The identity of the calling application could not be established') { | |
[String]$Message = "The application is not provisioned for customer $customer. Please have the customer " + | |
'perform admin consent by clicking the following link while logged in as a user that has rights to perform ' + | |
"admin consent: https://login.microsoftonline.com/$customer/adminconsent?client_id=$($ENV:APPID). Error: $PSItem" | |
} | |
if (-not $Message) { $Message = $PSItem } | |
#TODO: Guidance if tenant is not set up yet | |
Push-OutputBinding -Name Response -Value ( | |
[HttpResponseContext]@{ | |
StatusCode = [HttpStatusCode]::BadRequest | |
Body = [String]$Message | |
} | |
) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
To use this in an azure function you must provide the APPID, TenantId of your app, and app client secret of an app registration in your tenant. You must give it User.Read API permissions:
And your customers must adopt the app into their environment using the Admin Consent workflow. I recommend the URL method:
https://docs.microsoft.com/en-us/azure/active-directory/manage-apps/grant-admin-consent#construct-the-url-for-granting-tenant-wide-admin-consent