Microsoft Graph is an interface to the Microsoft 365 data. It allows you to create apps that work with Microsoft 365. This way, API access is possible directly from programming or scripting languages like PowerShell.
Here, an example of accessing Exchange Online mailboxes via this method will be explained.
A "Microsoft Work or School account" is needed.
Install-Module Microsoft.Graph -Scope AllUsers
Get-InstalledModule Microsoft.Graph
$AppName = 'Test Graph'
#SignInAudience can be the following values: "AzureADMyOrg", "AzureADMultipleOrgs","AzureADandPersonalMicrosoftAccount", "PersonalMicrosoftAccount"
$audience= "AzureADandPersonalMicrosoftAccount"
# Tenant to use in authentication.
$authTenant = switch ($audience)
{
"AzureADMyOrg" { "tenantId" }
"AzureADMultipleOrgs" { "organizations" }
"AzureADandPersonalMicrosoftAccount" { "common" }
"PersonalMicrosoftAccount" { "consumers" }
default { "invalid" }
}
if ($authTenant -eq "invalid")
{
Write-Host -ForegroundColor Red "Invalid sign in audience:" $audience
Exit
}
# Requires an admin
Connect-MgGraph -Scopes "Application.ReadWrite.All User.Read" -UseDeviceAuthentication -ErrorAction Stop
# Get context for access to tenant ID
$context = Get-MgContext -ErrorAction Stop
if ($authTenant -eq "tenantId")
{
$authTenant = $context.TenantId
}
# Create app registration
$appRegistration = New-MgApplication -DisplayName $AppName -SignInAudience $audience -IsFallbackPublicClient -ErrorAction Stop
Write-Host -ForegroundColor Cyan "App registration created with app ID" $appRegistration.AppId
# Create corresponding service principal
if ($audience-ne "PersonalMicrosoftAccount")
{
New-MgServicePrincipal -AppId $appRegistration.AppId -ErrorAction SilentlyContinue `
-ErrorVariable SPError | Out-Null
if ($SPError)
{
Write-Host -ForegroundColor Red "A service principal for the app could not be created."
Write-Host -ForegroundColor Red $SPError
Exit
}
Write-Host -ForegroundColor Cyan "Service principal created"
}
Write-Host
Write-Host -ForegroundColor Green "SUCCESS"
Write-Host -ForegroundColor Cyan -NoNewline "Client ID: "
Write-Host -ForegroundColor Yellow $appRegistration.AppId
Write-Host -ForegroundColor Cyan -NoNewline "Auth tenant: "
Write-Host -ForegroundColor Yellow $authTenant
Disconnect-MgGraph
Write-Host "Disconnected from Microsoft Graph"
The App Registration is like a Template for the actual App, which is Called Enterprise App. Enterprise Apps are "instances" of App Registrations. Every Enterprise App refers to exactly one App Registration, but a App Registration can be used for multiple Enterprise Apps.
Register and configure App in Microsoft Azure Admin Center!
Option | Who can sign in?
- Accounts in this organizational directory only | Only users in your Microsoft 365 organization
- Accounts in any organizational directory | Users in any Microsoft 365 organization (work or school accounts)
- Accounts in any organizational directory ... and personal Microsoft accounts | Users in any Microsoft 365 organization (work or school accounts) and personal Microsoft accounts |
Via Entra Admin Center -> Applications -> Enterprise Applications -> New application -> create your own application -> "Register an application to integrate with Microsoft Entra ID" -> Supported Account types = "Accounts in any organizational directory" (keep URI empty)
#App ID / Client ID
$clientId = "<ClientID/AppID of your app>"
#Tenant ID
$authTenant = "<yourTenantID"
#Scopes
$graphScopes = @("user.read", "mail.read", "mail.send")
# Authenticate the user
#$ClientSecretCredential = Get-Credential -Credential $settings.clientId -ClientSecretCredential $ClientSecretCredential
Connect-MgGraph -ClientId $clientId -TenantId $authTenant -Scopes $graphScopes -UseDeviceAuthentication
# <GetContextSnippet>
# Get the Graph context
Get-MgContext
# </GetContextSnippet>
# <SaveContextSnippet>
$context = Get-MgContext
# </SaveContextSnippet>
# <GetUserSnippet>
# Get the authenticated user by UPN
$user = Get-MgUser -UserId $context.Account -Select 'displayName, id, mail, userPrincipalName'
# </GetUserSnippet>
# <GreetUserSnippet>
Write-Host "Hello," $user.DisplayName
# For Work/school accounts, email is in Mail property
# Personal accounts, email is in UserPrincipalName
Write-Host "Email:", ($user.Mail + ' ' + $user.UserPrincipalName)
# </GreetUserSnippet>
Get-MgUserMailFolderMessage -UserId $user.Id -MailFolderId Inbox -Select `
"from,isRead,receivedDateTime,subject" -OrderBy "receivedDateTime DESC" `
-Top 25 | Format-Table Subject,@{n='From';e={$_.From.EmailAddress.Name}}, `
IsRead,ReceivedDateTime
$sendMailParams = @{
Message = @{
Subject = "Testing Microsoft Graph"
Body = @{
ContentType = "text"
Content = "Hello world!"
}
ToRecipients = @(
@{
EmailAddress = @{
Address = ("example@example.com")
}
}
)
}
}
Send-MgUserMail -UserId $user.Id -BodyParameter $sendMailParams
#And Disconnect
Disconnect-MgGraph
Following Script removes the Enterprise Application AND App Registration, to clean up the Test : )
# Requires an Azure Admin
Connect-MgGraph -Scopes "Application.ReadWrite.All User.Read" -UseDeviceAuthentication -ErrorAction Stop
#Note! -> A "Service Principal Object" in this context is the same as an "Enterprise Application"
$app = Get-MgServicePrincipal -Filter "DisplayName eq 'Test Graph'"
#the previous command only works if the Name of the App is unique, you can also use the following.
#$app = Get-MgServicePrincipal -Filter "AppId eq '<YourEnterpriseAppID/ClientID>'"
Remove-MgServicePrincipal -ServicePrincipalId $app.Id
Remove-MgApplicationByAppId -AppId $app.AppId
Disconnect-MgGraph
Write-Host "Disconnected from Microsoft Graph"
H@ppy H@cking :)