Incoming webhook connector – Office 365 for IT Pros https://office365itpros.com Mastering Office 365 and Microsoft 365 Mon, 17 Jun 2024 07:46:21 +0000 en-US hourly 1 https://i0.wp.com/office365itpros.com/wp-content/uploads/2024/06/cropped-Office-365-for-IT-Pros-2025-Edition-500-px.jpg?fit=32%2C32&ssl=1 Incoming webhook connector – Office 365 for IT Pros https://office365itpros.com 32 32 150103932 Using PowerShell to Post Channel Messages with Teams Workflows https://office365itpros.com/2024/06/17/teams-post-to-channel-workflow/?utm_source=rss&utm_medium=rss&utm_campaign=teams-post-to-channel-workflow https://office365itpros.com/2024/06/17/teams-post-to-channel-workflow/#comments Mon, 17 Jun 2024 07:00:00 +0000 https://office365itpros.com/?p=65181

Replacing the Incoming Webhook Connector with the Teams Post to Channel Workflow

Last week, I discussed the looming end in sight for Office 365 connectors following their retirement from SharePoint Online and Microsoft 365 Groups. Connectors are still supported to bring information into Teams channels and the incoming webhook connector is a popular choice to create posts in channels from different network sources. For instance, this article describes how to post a notification about a report about expiring Microsoft 365 groups while this article discusses how to post information about service degradation for Office 365 workloads.

Both articles show how to use PowerShell to format the information sent for posting to a channel through the incoming webhook connector. I wanted to do the same thing with Power Automate workflows, specifically with the workflow called Post to a channel when a webhook request is received, which seems very close in concept to the incoming webhook connector: both publish a public URL for information to be sent to, and both demand that the information is formatted in a certain way.

The problem I ran into is a dearth of knowledge about how to construct the request body with PowerShell to send to the workflow. I knew that an adaptive card is used, but the example in Microsoft’s documentation wasn’t a great starting point. But persistence pays and the examples of formatting cards for Teams are better, and the adaptive card designer helped to debug various elements. In the end, I had a solution, and here’s how it works.

Create the Workflow

Channels have a workflows option in their overflow […] menu. Go to the channel you want to use as the target for the notifications and select Workflows (Figure 1).

The workflows option in a channel menu.

Teams post to channel workflow.
Figure 1: The workflows option in a channel menu

Select Post to a channel when a webhook request is received from the screen listing available workflow templates (Figure 2).

Select a workflow template.
Figure 2: Select a workflow template.

The workflow needs an account to authenticate connections and post to the channel (this is different to the incoming webhook connector, which doesn’t need to authenticate using an account). The account must be a member of the host team. If, like me, the organization uses a utility account for this kind of operation, you’ll need to add the account to the team or select one of the existing team members. Figure 3 shows that the utility account is selected and validated (green tick). If you want to use a different account, click the […] menu and choose another account to connect.

Select an account to post notifications via the webhook.
Figure 3: Select an account to post notifications via the webhook

After collecting all the necessary information, the dialog displays the name of the target team and channel. You can choose a different team or channel at this point. Once the correct target is chosen, click Add workflow. Power Automate proceeds to create the workflow and responds with the workflow URI (Figure 4).

Power Automate creates the workflow URI.
Figure 4: Power Automate creates the workflow URI

Copy the URL and keep it safe because it is needed to tell Power Automate where to post payloads. When a payload arrives, Power Automate parses its content and if it’s OK, posts the content to the target channel.

If you forget to copy the URI, you can find it by opening the Workflows app, selecting the workflow, and copying it from the When a Teams webhook request is received step (Figure 5). To avoid potential confusion if multiple workflows of the same type are in use, I suggest that you take the opportunity to rename the workflow to make its purpose obvious.

Steps for the post to a channel when a webhook request is received workflow in the Teams workflow app.
Figure 5: Steps for the post to a channel when a webhook request is received workflow in the Teams workflow app

Posting Requests to the Workflow

It’s at this point that we do some PowerShell magic to create the request sent to the workflow URI. To create a realistic example, I decided to use the Get Service Health Graph API to retrieve the current health status for critical services running in the tenant, like Exchange Online, SharePoint Online, Teams, and so on.

The request is an adaptive card, which is composed of elements like text blocks, images, and fact set. I settled on a simple design composed of an image, a heading (text block), and a fact set. A fact has a name and a value. In this case, the name is a service (like “OneDrive for Business”) and the value is the current service health status (like “service degraded”).

I created a prototype adaptive card with indicators where to add the header and facts. Creating the facts is a matter of retrieving the service health status, filtering the data to extract the status for critical services, adding a graphic indicator for each depending on the health status. After generating the data, it was then a matter of formatting it in JSON to meet the requirements of the adaptive card schema and inserting the facts and header into the right places in the prototype adaptive card. The final step is to submit the request using the Invoke-MgGraphRequest cmdlet. Figure 6 shows the result.

Microsoft 365 service health status posted to a Teams channel via a workflow webhook.
Figure 6: Microsoft 365 service health status posted to a Teams channel via a workflow webhook

You can download the script from GitHub.

Normal Migration Woes

I am no Power Automate expert and profess no insight into how Power Automate works behind the scenes. I approached this exercise from the perspective of a tenant administrator who needs to replace the incoming webhook connector with a workflow. Persistence, some experience with PowerShell, knowledge of how to navigate Microsoft documentation, and trial and error got me a result in a few hours.

Overall, the transition was harder than I expected, but that might be due to lack of knowledge. It’s always difficult to do things when you suffer from that problem. I’ll chalk the experience down to normal migration woes.


Learn about using Teams, Power Automate, and the rest of Office 365 by subscribing to the Office 365 for IT Pros eBook. Use our experience to understand what’s important and how best to protect your tenant.

]]>
https://office365itpros.com/2024/06/17/teams-post-to-channel-workflow/feed/ 15 65181
The Abuse of Teams Inbound Webhook Connectors and Channel Email Addresses https://office365itpros.com/2024/03/18/incoming-webhook-connector-abuse/?utm_source=rss&utm_medium=rss&utm_campaign=incoming-webhook-connector-abuse https://office365itpros.com/2024/03/18/incoming-webhook-connector-abuse/#comments Mon, 18 Mar 2024 04:00:00 +0000 https://office365itpros.com/?p=64151

Phishing Attacks Against Teams

A March 14 article called Wishing: Webhook Phishing in Teams published by Black Hills Information Security discusses the potential malicious use of incoming webhooks for Teams channels. There’s a lot to read in the article and Black Hills say that they disclosed the issue described to Microsoft in January 2024. Apparently, the Microsoft Security Response Center (MSRC) closed the issue without a fix. But as reported below, some changes appear to be in progress to mitigate the problem by making the incoming webhook connector into a Teams app and limiting access to team owners.

The incoming webhook connector is one of many connectors supported by Teams. Incoming webhook connectors import snippets of information from external sources and post them as new conversations in the channel that hosts the connector.

The intent behind posting items is to inform team members about news to either spark a conversation within a team or to encourage users to follow up and discover more information about a topic, possibly by following a link in an adaptive card. Like any team message, the size of what a connector can post to a channel is limited to 28 KB.

When a team owner configures an incoming webhook connector for a channel, Teams generates a target URL for apps to post to. A channel can host multiple instances of the incoming webhook connector, each with its own URL. Webhook connectors do not use authentication, but messages posted through these connectors must follow a specific format.

The article describes how Black Hills built a module in the GraphRunner tool (available from GitHub) to fetch connector information from Teams channels. No public Graph API is available to retrieve connector information, so reverse engineering was necessary to track down the API endpoints and required tokens. The work traversed some artifacts of Teams history, such as the references to Skype Spaces and the outcome is a list of channels with URIs configured for the incoming web connector. The article also covers details about creating new incoming webhook connectors for channels.

Looks Like Microsoft is Changing the Way Inbound Webhook Connectors Work

Playing around with incoming webhooks using code like that described in the article about posting new Microsoft 365 roadmap items to Teams channels, I discovered that although it was possible to configure an incoming webhook for a channel using the new Teams, attempts to post to the URI failed with this error:

Invoke-RestMethod: Microsoft.Substrate.Connectors.Store.Exceptions.ExchangeInvalidGroupIdException: Exception of type 'Microsoft.Substrate.Connectors.Store.Exceptions.ExchangeInvalidGroupIdException' was thrown. ErrorCode:ErrorInvalidGroup

The error text implies that Teams couldn’t find the right group (team) to post to. However, if I configured the incoming webhook connector using the old Teams, the URI generated worked. Curiously, the URI generated by Teams classic for the connector uses one of the fallback domains for my tenant (https://derrigimlagh.webhook.office.com/) rather than the usual. (https://microsoft.webhook.office.com/). This implies that work is ongoing to update how Teams uses the incoming webhook connector and that Microsoft hasn’t implemented the code in Teams classic because the client is due to retire on March 31.

Another difference I noted is that a Teams app is now called the first time an owner configures the incoming webhook connector in a team (Figure 1). Management of the app is like any other Teams app, and it can be restricted to specific users via app permission policies.

The Incoming webhook app in the Teams admin center.

Incoming webhook connector
Figure 1: The Incoming webhook app in the Teams admin center

It would be normal for a security review to happen during the transition to a new version of a client. It seems like this might be happening as Microsoft prepares to make the Teams 2.1 client the norm.

Spamming Team Channel Email Addresses

Next, the discussion moves to email addresses for team channels. Email sent to these addresses do not go through the regular email environment for tenants and are handled by a special infrastructure created for Teams. However, the traffic still goes through Exchange Online Protection.

Channel email addresses recently created limit acceptance of inbound email to team members. It’s also possible to limit receipt to a specified list of domains. Older channels are likely to have the older default, which allows the channel to receive email from anywhere (Figure 2).

A team channel open for anyone to send email to
Figure 2: A team channel open for anyone to send email to

It’s probably a good idea to check channels to make sure that they’re not open for anyone to send to. Here’s an article about how to report channels with email addresses.

The article says that “Microsoft claims that this feature needs to be enabled by the Administrator, however, through testing, we can see this is not the case.” My testing shows that the controls on sending email to channels implemented in the Teams admin center work (Figure 3).

Email integration controls in the Teams admin center.
Figure 3: Email integration controls in the Teams admin center

With acceptance of channel email set to a limited number of domains, messages from other domains failed with the error:

The administrator has restricted permissions to send emails to this channel.

The authors of the report advise those who want to try out the phishing techniques to sign up for a free developer tenant. This kind of activity might be the reason why Microsoft has limited access to these tenants to those with a Visual Studio Enterprise license.

Check Your Tenant

The results I report here are accurate as of March 15, 2024. Given that it seems like some changes are happening to secure Teams better, so it’s wise to do your own tests to understand the current state of play in your tenant. As is always the case, attackers persist in seeking holes to exploit and things might change in the future in response. As good practice, tenant administrators should understand how information flows into Teams from external sources. It’s easy to control email to channels but the lack of a Graph API to report connectors makes that aspect harder. Let’s hope that Microsoft provides such an API and continues to tighten security around Teams.


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.

]]>
https://office365itpros.com/2024/03/18/incoming-webhook-connector-abuse/feed/ 2 64151
Post to Teams Channels from Azure Automation Scripts https://office365itpros.com/2022/04/08/post-teams-channels/?utm_source=rss&utm_medium=rss&utm_campaign=post-teams-channels https://office365itpros.com/2022/04/08/post-teams-channels/#comments Fri, 08 Apr 2022 01:00:00 +0000 https://office365itpros.com/?p=54456

From File Creation to Post to Teams Channels

About a month ago, I wrote about my experiences of creating files in SharePoint Online using a PowerShell script executing as an Azure Automation runbook. I reported that I used user credentials stored as a resource in the Azure Automation account to authenticate with the SharePoint PnP module. Once authenticated, I could use the Add-PnPFile cmdlet to create the file created by the script as a file in a SharePoint document library.

I noted that I used the stored credentials to make sure that I could create the file using the identity of a member of the Microsoft 365 group which owned the document library and hadn’t been able to find another way of doing this. I also said that I couldn’t find a way to post to Teams channels because of the way Graph permissions work. Clearly, I was exploring the limits of my knowledge.

Two comments made helpful suggestions. The first noted that the PnP PowerShell module includes a Submit-PnpTeamsChannelMessage cmdlet and suggested that this could be an answer, especially if combined with certificate-based authentication (CBA). The second suggested using the incoming webhook connector to post to a target channel.

Using Submit-PnpTeamsChannelMessage to Post to Teams Channels

My script created the output report in CSV and HTML files and already had a connection to PnP. The Submit-PnpTeamsChannelMessage cmdlet accepts HTML content as the message body for a channel. With the connection and body part in place, I could add post the message using this code:

$TargetTeamId = "107fe4dd-809c-4ec9-a3a1-ab88c96e0a5e"
$TargetTeamChannel = "19:6d688803124c48d6bfa796284e641e9d@thread.tacv2"
Submit-PnPTeamsChannelMessage -Team $TargetTeamId -Channel $TargetTeamChannel -Message $Body -ContentType Html -Important

The parameters are the identifiers for the team owning the target channel and the channel. The team identifier is easily found using the Get-Team or Get-MgGroup cmdlets:

Get-Team -DisplayName "Tenant Information" | ft GroupId, DisplayName

GroupId                              DisplayName
-------                              -----------
107fe4dd-809c-4ec9-a3a1-ab88c96e0a5e Tenant Information

Get-MgGroup -Filter "displayName eq 'Tenant Information'" | ft Id, DisplayName

Id                                   DisplayName
--                                   -----------
107fe4dd-809c-4ec9-a3a1-ab88c96e0a5e Tenant Information

Knowing the team identifier, we can fetch the channel identifiers using the Get-TeamChannel cmdlet:

Get-TeamChannel -GroupId 107fe4dd-809c-4ec9-a3a1-ab88c96e0a5e | ft Id, DisplayName

Id                                               DisplayName
--                                               -----------
19:078bef3cfb6c4c519d4f585f099c9c91@thread.tacv2 General
19:6d688803124c48d6bfa796284e641e9d@thread.tacv2 Planning 2021

The other parameters are self-explanatory. The only other point of interest to note is that the Important switch applies this marking to the message. Figure 1 shows the result.

Message posted to a Teams channel using a script running in Azure Automation
Figure 1: Message posted to a Teams channel using a script running in Azure Automation

Great! We can post a message to a Teams channel using content created by a script running in Azure Automation. The only remaining challenge is how to eliminate the use of the stored credentials. I’m still exploring that point.

Using the Incoming Webhook Connector to Post to Teams Channels

The Incoming Webhook Connector is one of the standard connectors supported by all teams channels. The function of the connector is to accept JSON-formatted content submitted to a URI identifying the target channel and post it as a new message to that channel. Here’s an example of using the webhook connector to post information about new Microsoft 365 roadmap items. Instead of posting a normal message to a channel, the connector posts message cards. These are intended to be notifications that new information is available and can include directions (like a hyperlink) to tell users where they can find the complete story. In my case, it was impossible to fit the complete report into a message card as this blew the maximum size limit for a card. I therefore ended up creating a card to tell the reader that a new version of the report was available together with a button for them to download the report (from SharePoint Online). Here’s the code I used:

# Post to Teams channel using an incoming webhook connector
$GroupWebHookData = 'The new report is available in <a href="' + $NewFileUri + '">' + 'Microsoft 365 Groups Expiration Report</a>'
$DateNow = Get-Date -format g
$Notification = @"
    {
        "@type": "MessageCard",
        "@context": "https://schema.org/extensions",
        "summary": "Microsoft 365 Groups",
        "themeColor": "0072C6",
        "title": "Notification: New Microsoft 365 Groups Expiration Report is available",
         "sections": [
            {
                "facts": [
                    {
                        "name": "Tenant:",
                        "value": "TENANT"
                    },
                    {
                        "name": "Date:",
                        "value": "DATETIME"
                    }],
                    "markdown" : "true"                   
                  }],
                "potentialAction": [{
                       "@type": "OpenUri",
                       "name": "Download the report",
                       "targets": [{
                           "os": "default",
                           "uri": "URI"
                 }],
    }  ]
   } 
"@

$NotificationBody = $Notification.Replace("TENANT","$TenantName").Replace("DATETIME","$DateNow").Replace("URI","$NewFileUri")
# Make sure you use the URI for your channel here.
$TargetChannelURI = "https://office365itpros.webhook.office.com/webhookb2/107fe4dd-809c-4ec9-a3a1-ab88c96e0a5e@b662313f-14fc-43a2-9a7a-d2e27f4f3478/IncomingWebhook/0a3dea30f595436ead8138334516911a/eff4cd58-1bb8-4899-94de-795f656b4a18"
$Command = (Invoke-RestMethod -uri $TargetChannelURI -Method Post -body $NotificationBody -ContentType 'application/json')     

The resulting message card posted to the channel is simple, but it gets the job done (Figure 2).

A message card posted to a Teams channel using the incoming webhook connector
Figure 2: A message card posted to a Teams channel using the incoming webhook connector

Getting the Job Done

The conclusion is that it’s possible to post messages to Teams channels using either the Submit-PnpTeamsChannelMessage cmdlet or inbound webhook connector. Both methods have their own limitations, but once you understand what the limitations are, it’s easy to decide which approach to take in different circumstances.

The full script I used to create the output in an Azure Automation runbook is available in GitHub.


Keep up with the changing world of the Microsoft 365 ecosystem by subscribing to the Office 365 for IT Pros eBook. Monthly updates mean that our subscribers learn about new developments as they happen.

]]>
https://office365itpros.com/2022/04/08/post-teams-channels/feed/ 3 54456
New URL Format for Incoming Webhook Used by Teams and Groups https://office365itpros.com/2021/02/03/incoming-webhook-connector-format/?utm_source=rss&utm_medium=rss&utm_campaign=incoming-webhook-connector-format https://office365itpros.com/2021/02/03/incoming-webhook-connector-format/#comments Wed, 03 Feb 2021 02:12:00 +0000 https://office365itpros.com/?p=41450

Connectors Must be Updated by April 11, 2021

Office 365 Notification MC234048 published on January 12 announces that Microsoft is improving the security of the “Microsoft Teams connector apps webhook.” That mouthful refers to the incoming webhook connector which can be attached to Microsoft 365 Groups or Teams channels to allow the posting of cards generated from information in network sources.

The webhook is a unique URL which applications use to address the channel where they wish to publish information. The change being made adds the tenant name to the webhook URL to make it more apparent than previous. According to Microsoft, security is improved through the presence of the tenant name because organizations can then use the information to filter traffic logs. Quite how this improves security is beyond me because the tenant identifier (a GUID) has always been present in the webhook URL.

The changeover to the new format started on January 11, 2021. Old format webhooks will continue working for three months. The webhooks must be updated to the new format by April 11, 2021 to ensure that information continues to flow.

Interpreting the Webhook URL

The new format webhook looks like this:

https://office365itpros.webhook.office.com/webhookb2/7aa49aa6-7840-443d-806c-08ebe8f59966@c662313f-14fc-43a2-9a7a-d2e27f4f3478/IncomingWebhook/8592f62b50cf41b9b93ba0c0a00a0b88/eff4cd58-1bb8-4899-94de-795f656b4a18

The component parts are of the webhook are:

  • Tenant name (taken from Azure AD): Office365itpros. This is the new piece added to the webhook URL.
  • Webhook root: webhook.office.com/webhookb2. Old webhook URLs use office.com/webhook.
  • Group identifier: The Azure AD identifier for the Microsoft 365 group. In the example, this is 7aa49aa6-7840-443d-806c-08ebe8f59966.
  • Tenant identifier: The Azure AD identifier for the tenant. In the example, this is c662313f-14fc-43a2-9a7a-d2e27f4f3478. The group and tenant identifiers are separated by an at sign.
  • Provider name: This is always “IncomingWebhook.”
  • Alternate identifier: Another GUID to make the URL unique because a group or channel can support multiple webhooks. In this case, it’s 8592f62b50cf41b9b93ba0c0a00a0b88.
  • Group owner: The Azure AD identifier (GUID) for the group owner. Or rather, the account of the owner who adds the webhook to the group.

The same connector is used to bring data in from external sources to both Teams (data is posted in a channel) and Microsoft 365 Groups (data is posted as topics in email conversations).

Updating a Connector

Updating a connector to use the new format webhook isn’t hard. The trick is to know where the connectors are currently configured. When you know that, a group owner can access the set of connectors and check the incoming webhook connector. If “Attention required” appears for the connector, the webhook must be updated (Figure 1). If not, the connector is using the new format.

Attention required for an incoming webhook connector in a Teams channel
Figure 1: Attention required for an incoming webhook connector in a Teams channel

Clicking Manage brings you to the connector settings (Figure 2). Click Update URL to generate a new format webhook URL and then Save to update the connector. Before you save, make sure that you copy the webhook URL as you’ll need this to update the applications which send data to Microsoft 365 Groups or Teams through the connector.

Updating the webhook URL for a connector
Figure 2: Updating the webhook URL for a connector

The applications might be as simple as a PowerShell script (here’s an example of posting Microsoft 365 roadmap items to Teams and another to post notifications about inactive mailboxes). In other cases, the webhook URL might be used to post information coming from an application.

Finding Teams Using the Incoming Webhook

If you have only a few teams configured with the incoming webhook it won’t be hard to find and update the URL. Things are a little more complex in large organizations where many webhooks might be in use for both Teams and Microsoft 365 Groups. In these circumstances, some help might be needed to find all the connectors.

Some time ago, I wrote a PowerShell script to show how to report the channels and tabs connected to Teams. The point of that post was to demonstrate the retrieval of large amounts of data from Teams. As each team has standard apps (like Calls)), can have up to 200 channels, and each channel can have multiple tabs (including standard tabs), the script collects a bunch of information. In this instance, we can use it to find which teams have connectors configured with the incoming webhook connector.

After running the script, we can query the output report to find instances of teams with the connector:

$Report | ?{$_.App -eq "incoming webhook"} | Format-Table Team

Team
----
Technology News and Views
Engineering Colleagues
Human Resources Group
PL Test
Industry News

The report doesn’t tell us for which channel the connector is configured, but that should be easily found.

In passing, if you want to get an insight into the number of standard apps installed by Teams, run this command to group the results in the report:

$Report | Group App | Sort Count -Descending | Format-Table Name, Count

As they say, the output is “interesting”!


Interpreting the real meaning of a Microsoft announcement takes experience and background knowledge. Learn from the best by subscribing to the Office 365 for IT Pros eBook. No bumpf, just knowledge.

]]>
https://office365itpros.com/2021/02/03/incoming-webhook-connector-format/feed/ 5 41450
How to Post Notifications About Unused Mailboxes to Teams https://office365itpros.com/2019/09/16/post-unused-mailboxes-teams/?utm_source=rss&utm_medium=rss&utm_campaign=post-unused-mailboxes-teams https://office365itpros.com/2019/09/16/post-unused-mailboxes-teams/#comments Mon, 16 Sep 2019 07:33:50 +0000 https://office365itpros.com/?p=3859

Extracting Unused Mailbox Information from Mailbox Diagnostics

Recently, I posted a Petri.com article to report the availability of some new properties in the Export-MailboxDiagnosticLogs cmdlet. The properties record different kinds of mailbox activity, and I included a script to generate a report based on the properties. The output is a CSV file that can be opened in Excel or imported in Power BI. All is well.

I then had the idea that maybe it would be good to filter the output to find unused mailboxes and post that information to a Teams channel as a form of proactive notification to administrators. Not having endless time, I browsed the web to find a PowerShell script to serve as a starting point and found one that reports inactive Active Directory accounts. That’s not a long way from what I wanted to do, so I grabbed the code and edited it to fit my purpose.

Using Incoming Webhook Connector to Post to Teams

Posting messages to a Teams channel is easily done using the incoming webhook connector, one of the standard connectors available to all Microsoft 365 tenants to bring information sourced from applications into Teams and Microsoft 365 Groups. When you configure the connector for a channel, you get a webhook (unique identifier) to post messages to the channel.

I then filtered the set of mailboxes I created in the table generated by the previous script (see link above) to find mailboxes with no email activity over the last 90 days. If a mailbox has no activity in three months, it’s a good indicator that it is an unused mailbox. I then generate the necessary JSON format payload consumed by Teams and post the resulting message reporting the unused mailboxes to the webhook. Here’s the script:

# Script uses some code from https://www.thelazyadministrator.com/2018/12/11/post-inactive-users-as-a-microsoft-teams-message-with-powershell/

$WebHook = "https://outlook.office.com/webhook/42f6d6b0-c191-496d-85b4-bfd6e63e230b@b662313f-14fc-43a2-9a7a-d2e27f4f3478/IncomingWebhook/62c92a65258a416b90e969980ae4ebb1/eff4cd58-1bb8-4899-94de-795f656b4a18"

$InactiveTable = New-Object 'System.Collections.Generic.List[System.Object]'
$PersonImage = "https://img.icons8.com/cotton/2x/gender-neutral-user--v1.png"
$Today = (Get-Date)
ForEach ($R in $Report) {
   $DaysSinceLastEmail = ((New-TimeSpan –Start $R.LastEmail –End $Today).Days)
   If ($DaysSinceLastEmail -gt 90) {
   $UserData = @{
     ActivityTitle = "$($R.Mailbox)"
     ActivitySubTitle = "-----------------------------------------------"
     ActivityText = "$($R.Mailbox)'s last email activity was on $($R.LastEmail)"
     ActivityImage = $PersonImage
     Facts = @(
        @{	
	  name  = 'Mailbox:'
	  value = $R.Mailbox 	},
	@{
	  name  = 'Last Email activity:'
	  value = $R.LastEmail 	},
	@{
	  name  = 'Days since last activity:'
	  value = $DaysSinceLastEmail	},
	@{
	  name  = 'Last active time (unreliable):'
	  value = $R.LastActive 	} )
	}
   $InactiveTable.Add($UserData)
   Write-Host $R.Mailbox $R.LastEmail $DaysSince }}

$Body = ConvertTo-Json -Depth 8 @{
	Title = "Possibly Inactive Office 365 Users"
	Text  = "There are $($InactiveTable.Count) users with no detected email activity for 90 days or more"
	Sections = $InactiveTable }

# Only post if we have less than 25 items
If ($InactiveTable.Count -lt 25) {
    Write-Host "Posting inactive account information to Teams" -ForegroundColor Yellow
    Invoke-RestMethod -uri $WebHook -Method Post -body $body -ContentType 'application/json' }
Else {
    Write-Host "Too many (" $InactiveTable.Count ") inactive accounts found to post to Teams... Spread the bad news another way" }

The message posted to Teams looks like the example shown in Figure 1:

Unused mailbox information posted to a Teams channel
Figure 1: Inactive Office 365 user information posted to a Teams channel

Remember the Teams Maximum Message Size

There’s nothing earth shattering in the code and plenty of similar examples are available online (such is the joy of PowerShell). What is important to note when you post to Teams is that the message is limited to a maximum size of 25 KB. If your message exceeds the limit, Teams responds with a HTTP 413 error similar to:

Microsoft Teams endpoint returned HTTP error 413 with ContextId tcid=982653230009892365,server=DB3PEPF00000461,cv=4LrmcZGylkmtD0uEToTT2g.0.

In my case, it seemed like the error happened if more than 28 or so items were in the list of reported accounts. This will obviously vary depending on how much data you try to post for each item.


For more information about using Teams and Microsoft 365 Groups with connectors, read the Office 365 for IT Pros eBook.

]]>
https://office365itpros.com/2019/09/16/post-unused-mailboxes-teams/feed/ 8 3859