Vue normale

Il y a de nouveaux articles disponibles, cliquez pour rafraîchir la page.
À partir d’avant-hierFlux principal

Reporting on Teams shared channels & users

One of the core principles I live my life by is to be informed, to know something fully before I make a decision.

Maybe it’s because I’m Autistic, maybe it’s just common sense, maybe it’s how I was raised, whatever — let’s not get philosophical here.

Virtually every organisation I’ve spoken to has said they’ve disabled shared channels in Microsoft Teams until they know more about it, and some have actually engaged me to help them with a framework for using it.

There are a number of challenges with shared channels, and that comes from the fact it’s trying to provide more granularity than guest access currently does, while at the same time trying to be flexible and easy to use — and we know you generally can’t have all of these together.

For those that have chosen to allow access to external channels and users, how do they know where their people are — and who is inside their tenant?

While there is some reporting in the Teams Admin Center (TAC), we have to dig into each Team, then each shared channel, and only then we can we find the external users and where they came from.

Thankfully we have a few endpoints in Microsoft Graph we can use to build some of our own reporting, using Power Automate to call the Graph endpoints and Power BI to visualise the data.

You can store the data in SharePoint Lists, Dataverse tables, or whatever you like.

There are a few aspects to capture in order to get a full picture:

  • Organisations that have been configured in for cross-tenant access in Azure AD
  • Shared channels attached to Teams
  • Internal users accessing shared channels in other organisations
  • Users from other organisations accessing shared channels in your tenant
  • Identifying what internal shared channels the external users are in

DISCLAIMER: Some of these calls are using beta endpoints and are technically not supported — so use at your own peril/pleasure.

Pre-requisites

Before we can create any workflows that call Graph, you will need an Azure AD App Registration with the following permissions:

  • Channel.ReadBasic.All
  • ChannelMember.Read.All
  • CrossTenantInformation.ReadBasic.All
  • CrossTenantUserProfileSharing.Read.All
  • Directory.Read.All
  • Policy.Read.All

You’ll also need to already have (or build) a listing of:

  • Users — ID & display name
  • Teams — ID & display name

Key workflows

In all of my workflows, I use a variable called “GraphPath” and sometimes “GraphPathSuffix” to help make the design of them more scalable and repeatable, so where applicable I will include those variables.

List organisations configured for cross-tenant access

Here we will use two key requests:

First, let’s list all the partners we have defined in Azure AD:

As this only returns the tenant ID, we need to run a second call against each of them to capture their organisation name and primary domain:

The data we’ll record looks like this:

And in Power BI our output looks like this:

Listing shared channels in your tenant

Ideally you already have a list of Teams in your tenant stored somewhere, if you don’t — you’ll need it for this next step.

Here we will use one key request:

The two parameters we’re using for our call are:

We’re then going to use both of these together with the Group ID of the Teams to see what shared channels exist:

For each channel we find, we’ll store these values:

Using a relationship between the “tenantid” value in this table and the same value in the table from the previous step we can start to build this out:

Where the values are blank in the “Remote Tenant” column, this is because the tenant is not external (i.e. the channel is hosted in our tenant).

List internal users accessing shared channels in other organisations

Here we will use two key requests:

Let’s set our Graph query elements:

The first step is to simply find who in our tenant is accessing external tenants, with the only result being their ID:

For each of those users, we now need to extrapolate and find the related tenants:

Then for each tenant returned, we only need to store the user ID and external tenant ID:

Again, using a relationship between the “tenantid” value in this table and the same value in the table from the previous step we can start to build this out:

List users from other organisations accessing shared channels in your tenant

Here we will use two key requests:

To see who from other organisations is inside of our tenant, our query is this:

And our action is simple:

Then for each result we find, we need to store the external user’s ID, display name, and home tenant ID:

Again, using a relationship between the “homeTenantId” value in this table and the same value in the table from the previous step we can start to build this out:

Connecting the dots

List which external users are in which shared channels

As we already have a list of shared channels stored in a table somewhere (in my case, it’s in Dataverse), we can now run a query against them.

Using this, we can now go beyond just having a listing of knowing which external users in are in shared channels, but knowing which users are in which channels themselves.

In my query to list those channels, I’ve used the existing “TenantID” variable I declared in my workflow to use with the Azure AD App Registration, so this will filter only channels that are in our tenant:

For each channel we want to list the members:

We again use our tenant ID to filter out any members who are internal, and I’ve also put a condition in place to only proceed if the resulting list has anything in it by using length(body(‘Filter_array_-_only_include_external_users’)):

For any users that do exist, we now record them in our table:

Over in Power BI we’ll establish a relationship between the Channel ID of the shared channels table and the Channel ID from this table (along with some filtering to remove channels where the “User IDs” column is empty), as well as the User ID from this table and the previous listing to get the following result:

Now, if you’re wondering why the list of external users is smaller in this list than in the previous list, it’s because there are effectively two components of the external users that exist:

  • Their inbound user profile
  • Their membership in a channel

Through the course of creating this solution, what I’ve discovered is that if you invite an external user to a shared channel, but they don’t accept the invitation — they will not show up as members of the channel.

It’s for this reason we need to maintain both lists of data (which could be addressed through better Power BI reporting skills than what I possess) — to understand where external users are in your tenant, and where they aren’t. This is the same as what we must do for Azure AD B2B guest users who may exist as an object in your directory, but not actually be a member of a M365 Group or Team (for any number of reasons, such as the Team no longer existing, they were removed by an owner, etc.).

Summary

As I started this blog post saying, it’s important to know what we are working with before we make decisions, as well as to provide troubleshooting and support in scenarios where things aren’t working the way we expect.

While a lot of what I’ve shown is possible in PowerShell, my preference is to do this using Power Automate, HTTP calls to Microsoft Graph, store the data in Dataverse tables, and report them with Power BI as it provides me with a solution that can continually operate without human intervention, as well as storing and displaying the data in a way that stakeholders and decision makers can access easily.

You may have reached this point and be wondering where the code for all this is, as I often publish the components on GitHub. As some of this was worked out during the course of writing this blog post, the workflows are not exactly in the most effective structure they could be.

Once I’ve cleaned them up, I’ll publish them on GitHub and update this blog post. For now, I’ve hopefully provided enough information for you to start building out your own reports.

Originally published at Loryan Strant, Microsoft 365 MVP.


Reporting on Teams shared channels & users was originally published in REgarding 365 on Medium, where people are continuing the conversation by highlighting and responding to this story.

Teams External Federation and Presence Privacy

Teams External Federation Enables Chat with Teams and Skype Users

External federation has existed in Microsoft integrated communications applications for a long time. Teams has supported federated chat with users in other Microsoft 365 tenants since 2019 and generally it all works very well, including federation with Teams consumer users and Skype consumer users.

If problems do occur when attempting to chat with a Teams user in another tenant, the usual cause is that the external access configuration for either tenant blocks communication. By default, the external access configuration allows connections to all other tenants, but it can be restricted to specific domains. For instance, one way to block the GIFShell exploit (when an external user sent an infected GIF to a Teams user), is to only permit federation with selected tenants.

Presence States

Presence is an important feature of online chat. It allows other people to know if you’re available. Teams supports several presence states such as Available, Busy, and Do Not Disturb You can even appear to be offline. Presence can have a duration. For instance, you can set presence to be Do Not Disturb for the next two hours, after which Teams resets your presence to Available.

While most people set their presence by clicking the avatar in the top right-hand corner of the Teams desktop or browser client (top left-hand corner for the mobile clients), force of habit means that I like using the command box to input my presence status there. Teams supports the following presence shortcuts:

  • /available
  • /away
  • /busy
  • /brb (be right back)
  • /dnd (do not disturb)
  • /offline

Making Presence Private in Teams External Federation

By default, your presence information is available in a Teams federated chat. This seems like a logical thing to do. After all, you’re communicating with someone for a reason. But an argument exists that it’s not good to let external people know your presence. For instance, if I go to a federated chat and view the person’s profile card (click on their avatar), I see their presence information, which is available even if a chat is inactive (Figure 1).

Presence information available for a federated chat user

Teams external federation
Figure 1: Teams external federation reveals presence information for an external user

The Set-CsPrivacyConfiguration cmdlet (which the documentation says goes back to Lync Server 2010) is now part of the Teams PowerShell module. A setting in the cmdlet controls the tenant privacy mode. By default, Teams disables privacy mode. To enable privacy mode, run the cmdlet and set the EnablePrivacyMode parameter to True:

Set-CsPrivacyConfiguration -EnablePrivacyMode $True

It can take several hours for the change to the configuration to propagate across Microsoft 365. When it’s active, presence information doesn’t appear in federated chats (Figure 2).

 Presence information is unavailable for a federated chat user
Figure 2: Teams external federation can’t display presence information for an external user

To revert, run Set-CsPrivacyConfiguration and set the EnablePrivacyMode parameter to False:

Set-CsPrivacyConfiguration -EnablePrivacyMode $False

Enabling privacy mode does not suppress the display of the person’s contact information and Teams never displays photos for federated users. It’s possible to add photos for guest accounts in the local Azure AD but not for federated users. I recommend that you do this for “persistent” guest accounts, those that are likely to remain in your directory for extended periods because of their business relationship with the organization.

Privacy Mode On or Off for All

I don’t think that many organizations will rush to enable privacy mode for Teams federated chat. It’s a feature that’s available but it’s also a mode that applies for the entire tenant. In other words, you cannot enable privacy mode for specific users and leave it off for the remainder. Many Teams policies are per-user for maximum flexibility. I suspect that the age of this policy is a contributing factor to why it’s a simple on/off switch.


Learn more about how the Office 365 applications really work on an ongoing basis by subscribing to the Office 365 for IT Pros eBook. Our monthly updates keep subscribers informed about what’s important across the Office 365 ecosystem.

❌
❌