Using Secure Model Authentication to manage Azure AD on multiple tenants

I set myself what I thought would be a simple automation task today. I want to start syncing our clients Azure AD to Autotask to automatically create contacts. Will save an extra step when we onboard a new client or user.

To do this we have to do two things, register an app in the clients Azure AD, and grab the ID of a group that contains all the users you want to sync.

To simplify this I thought I’d use PowerShell to create a Dynamic Group on each tenancy with the same name, with a rule in it to to include all active licenced users, and grab its ID along with the clients tenant name into a CSV. Then when I need it I can just copy and paste it.

Turns out that is a little more awkward than I thought. First issue is that creating Dynamic Groups using the New-AzureADMSGroup is still a preview feature, so I needed to run:

Remove-Module
Import-Module AzureADPreview

Next I had to generate the application secret and keys on our tenancy to authenticate as a partner. I did that using Kelvin Tegelaar’s script: Connect to Exchange Online automated when MFA is enabled (Using the SecureApp Model) – CyberDrain

Running this and following all its authentication prompts generates the authentication keys you need. Keep them safe!

Next I grabbed the script from here: Re: Exchange Online and the Secure App Model – Page 2 – Microsoft Partner Community that put it all together, and came up with my final script.

Note that dynamic groups only work if the client has Azure AD P1 or higher, and it turned out that far fewer of my clients have it than I thought!

remove-module azuread
import-module AzureADPreview 
$ApplicationId         = 'Paste Application ID here as from CyberDrain Script'
$ApplicationSecret     = 'Paste Application Secret here as from CyberDrain Script' | Convertto-SecureString -AsPlainText -Force
$TenantID              = 'Your (Partners) Tenant ID'
$Upn = 'Your email address'

$RefreshToken          = 'Paste Refresh Token here as from CyberDrain Script (it will be very long)'
$ExchangeRefreshToken  = 'Paste Refresh Token here as from CyberDrain Script (it will be very long)'

# CSP Partner connection:
$credential = New-Object System.Management.Automation.PSCredential($ApplicationId, $ApplicationSecret)

$aadGraphToken = New-PartnerAccessToken -ApplicationId $ApplicationId -Credential $credential -RefreshToken $refreshToken -Scopes 'https://graph.windows.net/.default' -ServicePrincipal -Tenant $tenantID 
$graphToken = New-PartnerAccessToken -ApplicationId $ApplicationId -Credential $credential -RefreshToken $refreshToken -Scopes 'https://graph.microsoft.com/.default' -ServicePrincipal -Tenant $tenantID 

Connect-AzureAD -AadAccessToken $aadGraphToken.AccessToken -AccountId $Upn -MsAccessToken $graphToken.AccessToken -TenantId $tenantID

# Find all your Customers/Clients
$Customers = Get-AzureADContract -All $True | select DefaultDomainName, CustomerContextID
# Disconnect from your AzureAD
Disconnect-AzureAD

#Loop through each tenant
foreach($customer in $Customers){

#Connect to the tenant
$CustAadGraphToken = New-PartnerAccessToken -ApplicationId $ApplicationId -Credential $credential -RefreshToken $refreshToken -Scopes 'https://graph.windows.net/.default' -ServicePrincipal -Tenant $Customer.CustomerContextId
$CustGraphToken = New-PartnerAccessToken -ApplicationId $ApplicationId -Credential $credential -RefreshToken $refreshToken -Scopes 'https://graph.microsoft.com/.default' -ServicePrincipal -Tenant $Customer.CustomerContextId
# Connect to Tenant's Azure AD
Connect-AzureAD -AadAccessToken $CustAadGraphToken.AccessToken -AccountId $upn -MsAccessToken $CustGraphToken.AccessToken -TenantId $customer.CustomerContextId

# Create Dynamic group
New-AzureADMSGroup -DisplayName "Azure AD Sync" -Description "Dynamic group for Syncing to Autotask" -MailEnabled $false -MailNickName "group" -SecurityEnabled $true -GroupTypes "DynamicMembership"  -MembershipRuleProcessingState "On" -MembershipRule "(user.accountEnabled -eq True) and (user.objectId -ne null) and (user.userType -eq ""Member"") and not (user.assignedPlans -all (assignedPlan.servicePlanId -eq """"))"

$groupresult = get-azureadmsgroup -SearchString "Azure Ad Sync"

#Write Tenant's Domain name and the Group ID to a CSV
Add-Content -Path .\Groups.csv -Value "$($customer.DefaultDomainName), $($groupresult.id)"

#Screen output so you know it is doing something!
write-host $customer.DefaultDomainName, $groupresult.id, " Tenant ID ", $customer.CustomerContextId
# Then: Disconnect-AzureAD  when done with each Customer, unless also connecting to ExchOnline
Disconnect-AzureAD

}





My next step may be to generate the application and write out the apps ID and secret for importing to Autotask.