Exchange Online Setup 

To restrict app access to specific mailboxes, you need the Exchange Online PowerShell module.

Prerequisites 

PowerShell 7.x (latest recommended) is required for best compatibility. Windows PowerShell 5.1 works but may have limitations with newer module versions.

Check your version:

$PSVersionTable.PSVersion
Copied!

Install or update to PowerShell 7:

winget install Microsoft.PowerShell
Copied!

Install the ExchangeOnlineManagement module. Run PowerShell as Administrator:

Install-Module -Name ExchangeOnlineManagement -Force -AllowClobber
Copied!

Import and connect 

Import-Module ExchangeOnlineManagement
Connect-ExchangeOnline -UserPrincipalName your-admin@yourdomain.com
Copied!

This opens a browser window for authentication. Use an account with Exchange Admin rights.

Create the Application Access Policy 

The New-ApplicationAccessPolicy cmdlet restricts your application to only access specific mailboxes instead of all mailboxes in the tenant.

Parameters:

  • -AppId: The Application (client) ID from your Microsoft Entra ID app registration
  • -PolicyScopeGroupId: The email address of the mailbox or mail-enabled security group the app is allowed to access
  • -AccessRight RestrictAccess: Limits the app to only the specified mailbox(es)
  • -Description: A human-readable description for the policy
New-ApplicationAccessPolicy -AppId "<your-app-id>" -PolicyScopeGroupId "shared@yourdomain.com" -AccessRight RestrictAccess -Description "Restrict to shared mailbox"
Copied!

To verify the policy was created:

Get-ApplicationAccessPolicy | Format-List
Copied!

To test if the policy works correctly:

Test-ApplicationAccessPolicy -Identity "shared@yourdomain.com" -AppId "<your-app-id>"
Copied!

Using Shared Mailboxes 

If you see an error like this when creating the policy:

The policy scope "shared@yourdomain.com" is not a valid mail-enabled security group.
Copied!

You need to create a mail-enabled security group and add the shared mailbox to it.

Create a mail-enabled security group 

1. Create the security group via PowerShell:

New-DistributionGroup -Name "Graph API Shared Mailboxes" -Type Security -PrimarySmtpAddress "graph-mailboxes@yourdomain.com"
Copied!

2. Add your shared mailbox to the group:

Add-DistributionGroupMember -Identity "Graph API Shared Mailboxes" -Member "shared@yourdomain.com"
Copied!

3. Verify the group was created correctly:

Get-DistributionGroup -Identity "Graph API Shared Mailboxes" | Format-List
Get-DistributionGroupMember -Identity "Graph API Shared Mailboxes"
Copied!

4. Now create the Application Access Policy using the group:

New-ApplicationAccessPolicy -AppId "<your-app-id>" -PolicyScopeGroupId "graph-mailboxes@yourdomain.com" -AccessRight RestrictAccess -Description "Allow app to send from shared mailboxes"
Copied!

5. Test the policy:

Test-ApplicationAccessPolicy -Identity "shared@yourdomain.com" -AppId "<your-app-id>"
Copied!

You should see AccessCheckResult: Granted.

Adding multiple mailboxes 

Simply add additional mailboxes to the same security group you already created:

Add-DistributionGroupMember -Identity "Graph API Shared Mailboxes" -Member "another-shared@yourdomain.com"
Copied!

The Application Access Policy applies to all members of the group – no need to create a new policy.

Verify it worked:

# List all members of the group
Get-DistributionGroupMember -Identity "Graph API Shared Mailboxes"

# Test the new mailbox
Test-ApplicationAccessPolicy -Identity "another-shared@yourdomain.com" -AppId "<your-app-id>"
Copied!

Alternative via Microsoft 365 Admin Center 

  1. Go to Admin Center → Teams & Groups → Active teams & groups
  2. Click Add a group and select Mail-enabled security
  3. Name the group (e.g., "Graph API Shared Mailboxes")
  4. Add the shared mailbox as a member
  5. Then run the New-ApplicationAccessPolicy command with that group's email address

Troubleshooting 

# Check if connected
Get-ConnectionInformation

# Verify cmdlet exists
Get-Command New-ApplicationAccessPolicy

# Check PowerShell version (needs 5.1+)
$PSVersionTable.PSVersion

# List all existing policies
Get-ApplicationAccessPolicy | Format-List

# Remove a policy if needed
Remove-ApplicationAccessPolicy -Identity "<policy-id>"
Copied!