Know Who’s Collaborating Outside Your Tenant
When Microsoft launched Teams shared channels into public preview (according to MC390413, shared channels will GA in mid-July 2022) the rubber hit the road as tenant administrators tried to figure out the complexities of managing shared channels in production use. It’s true that Microsoft conducted a long private preview with many customers to get shared channels to the point where they squashed obvious bugs and delivered usable software. However, once software is exposed to the kind of examination that an application with 270 million monthly active users can create, other questions bubble to the surface.
Which brings me to the topic of controlling user access to shared channels. The cross-tenant access settings in the External identities section of the Azure AD admin center control which tenants your organization can access using Azure AD B2B Direct Connect. This is the underlying authentication mechanism for Teams shared channels. It allows users to authenticate in their home tenant and use that authentication, including MFA and device state claims, to access resources in other tenants, if permitted by other tenants.
Azure AD Sign-Ins Track Cross-Tenant Access
Microsoft’s guidance for cross-tenant access settings advises that you can use Azure AD sign in logs to figure out user access to other tenants. It’s true that you can use the PowerShell snippet provided there, but I think we can do better.
The code uses the Get-MgAuditLogSignIn cmdlet from the Microsoft Graph PowerShell SDK to look for sign in records where the resource tenant identifier (the organization delivering a resource like Teams) is not the same as the home tenant identifier (the organization holding the Azure AD sign in logs).
Get-MgAuditLogSignIn -Filter "ResourceTenantId ne '$TenantID'" -All:$True
The code works (the All switch doesn’t need $True), but the result of the query is a set of sign-in records for both Azure AD B2B Collaboration (guest accounts) and Azure B2B Direct Connect. This is a better filter if you want to focus on access to Teams shared channels:
Get-MgAuditLogSignIn -Filter "ResourceTenantId ne '$TenantID' and CrossTenantAccessType eq 'b2bDirectConnect'" -All
Next, although you might recognize the identifier for your tenant, it’s unlikely that you’ll know the identifiers for other tenants (like 22e90715-3da6-4a78-9ec6-b3282389492b). To translate these identifiers into human-friendly tenant names, we need another method.
We’re already connected to the Microsoft Graph, so we can use a Graph query to resolve the identifier into a tenant name.
Finding Tenant Names
Fortunately, a beta query called findTenantInformationByTenantId does the trick. There’s little documentation available, but by running it through the Invoke-MgGraphRequest cmdlet (runs any Graph query when an SDK cmdlet is unavailable), we can retrieve tenant data:
$ExternalTenantId = $Record.ResourceTenantId $Uri = "https://graph.microsoft.com/beta/tenantRelationships/findTenantInformationByTenantId(tenantId='$ExternalTenantId')" $ExternalTenantData = Invoke-MgGraphRequest -Uri $Uri -Method Get
The tenant information returned is:
Name Value ---- ----- @odata.context https://graph.microsoft.com/beta/$metadata#microsoft.graph.tenantInformation tenantId 22e90715-3da6-4a78-9ec6-b3282389492b displayName o365maestros federationBrandName defaultDomainName o365maestros.onmicrosoft.com
I assume this web site, which can return the identifier of any Microsoft 365 tenant, uses a similar API.
Flow of the Script
The flow of the PowerShell script to analyze sign-in data is therefore:
- Find sign-in records for Azure B2B Direct Connect activity. If you want to process records for Azure B2B Collaboration, change the filter to remove the check against the CrossTenantAccessType property.
- Extract data from each record, including resolving external tenant identifiers to tenant names.
In normal circumstances, the sign-in data will feature just a few tenants. It would be slow to run a query to resolve the tenant identifier for every record. To ensure performance, the script resolves a tenant name the first time it is encountered and stores the tenant name identifier and name in a hash table. When the script processes subsequent records for the same tenant, it reads the information from the hash table.
You can download the script from GitHub. Normal warnings apply: use at your peril, etc. and please fix my bugs…
The output of the script is a PowerShell list containing details of sign-ins which use cross-tenant access to connect to Teams shared channels in external tenants (Figure 1).
The data can be parsed to reveal statistics like which tenants use cross-tenant access:
$Report | Group TenantName | Sort Count -Descending | Format-Table Name, Count
Or to reveal the names of the users who connect to external tenants:
$Report | Group User | Sort Count -Descending | Format-Table Name, Count Name Count ---- ----- Sean Landy 4 James Ryan 3 Ken Bowers 3
And so on. I’m sure you’ll find other ways to use the information to track what’s happening with Teams shared channels. The point is that the data is there if you need it. All that’s required is a little massaging of the information.
Insight like this doesn’t come easily. You’ve got to know the technology and understand how to look behind the scenes. Benefit from the knowledge and experience of the Office 365 for IT Pros team by subscribing to the best eBook covering Office 365 and the wider Microsoft 365 ecosystem.