Sunday, June 9, 2024

Manage Teams Tenant Blocked Numbers with Power Platform and Azure Automation

Manage Teams Tenant Blocked Numbers

Solution Background

If you are using Microsoft Teams for voice communication, you may have encountered some annoying or unwanted calls from telemarketers, spammers, or pranksters. While individual users have the capability to block unwanted calls right from within the Teams client, you may have wondered how to block these numbers from reaching your organization entirely.

Fortunately, there are many flexible options available by leveraging Power Platform, Azure Automation, Microsoft Graph and the underlying PowerShell commonly used by tenant admins for automation.

For reference, this automation is built from the tenant administration documentation found HERE.


Platform Value

Although this task could be easily handled with PowerShell, I aim to showcase the broader concept of low-code development by integrating Power Platform with Teams Tenant administration and Azure Automation. These concepts can be applied to various automation needs, enabling you and your organization to reduce manual steps, minimize command-line errors, and scale tenant administration for those unfamiliar with PowerShell or MS Graph.

General Implementation

First, I need to clarify, this initial post will not include a detailed step-by-step walkthrough of the configuration. I plan to post those specific guides and downloadable examples on GitHub. For now, this post covers the key concepts to inspire creative thinking.

This example is highly flexible. While I used a Dataverse table to store and display data in a Gallery, you could also use a SharePoint list, Power BI, or even a simple Excel table. Additionally, you could configure the PowerApp to display only active tenant pattern block information. This is how I initially started, but I later recognized the value in including additional fields to document "who" submitted the blocked number request, "when" it was submitted, and the "why" or reason category.


Starting with Power Apps - determine your intent. Do you want to include additional data outside what is stored in Teams, and if so - is Dataverse, Sharepoint or Excel more flexible for you ?

In my example - I chose the following components and controls:

The initial OnStart parameters for our app - sets the global variables:

Set(runbookActive, false); Set(jobId, ""); Set(JobStatus, Text("No Job Initiated"));


As noted in the diagram, a basic layout in the canvas app, with input text controls and submit buttons for inserting new blocked records using variables (OnSelect):

Set(jobId,Blank());Set(runbookActive,true);
Set(JobStatus, "Job Executing ... Please wait");
Set(jobId,setBlockedNumber.Run(inputName.Value, inputDescription.Value, inputPattern.Value, inputReqestor.Value, dropdownReason.Selected.Value).jobid);
Reset(inputName);
Reset(inputDescription);
Reset(inputPattern);
Reset(inputReqestor);
Reset(dropdownReason);
UpdateContext({ startTimer: true });
Refresh('Blocked Phone Numbers')

A button to remove blocked numbers based on the selected row in the Gallery (OnSelect):

Set(jobId,Blank());Set(runbookActive,true);
Set(JobStatus, "Job Executing ... Please wait");
Set(jobId,remBlockedNumber.Run(Table1.Selected.'Block Name', Table1.Selected.'Blocked Phone Numbers').jobid);
UpdateContext({ startTimer: true });
Refresh('Blocked Phone Numbers')

And a creative idea to leverage a timer control which is hidden from the user, which executes a Get Job Status every 2 seconds, to show the user the status of the job, and when it completes. (OnTimerEnd)

Set(JobStatus, updateStatus.Run(jobId).jobstatus);
If(JobStatus = "Completed", Refresh('Blocked Phone Numbers');
UpdateContext({ startTimer: false }));


In Power Automate we leverage 4 flows:

  • getBlockedNumbers (to retrieve current tenant blocked numbers and update our Dataverse table)
  • setBlockedNumber - to insert a new pattern block
  • remBlockedNumber - to remove selected blocked pattern or range
  • updateStatus - triggerd from the PowerApp timer control, on timer end. The Timer ends every 2 seconds, runs the update status (using Get Job Status, with the jobId from the triggered job - get, set or remove).
Each of these flows starts with the PowerApps (V2) trigger and leverages an Azure Automation Job to execute the PowerShell Runbook.

Azure Automation Create Job:


It responds to the Power App with the JobID for reference to update the Job Status text control:

And then add the new row to Dataverse, or whichever data structure you prefer:


As I mentioned, I will cover these steps in more detail. Specifically the Job Status and Timer Control, JSON format to ingest records to Dataverse and also the remove row function - as this did get a little tricky, needing to find and use the Dataverse Record GUID which is often a hidden value in the Dataverse table, and needs to be exposed in order to define the GUID as a dynamic context variable.


Then we duplicate each flow to incorporate get, set, remove and check status.


To tie in the magic, an Azure Automation account is needed, with appropriate permissions. Create an automation account associated with the resource group desired, and a role assignment


And each Runbook which contains the PowerShell commands:


As of this post, I chose to implement a separate runbook for each powershell function (one for get, set and remove). I do plan to consolidate this and leverage an input parameter for the 3 commands under one runbook.


Planner

Even when working independently, I prefer using Planner with a Kanban-style board to track my activities. I usually work in hour-long intervals (if I'm lucky), making it challenging to prioritize and complete tasks. The backlog feature helps me identify the minimum viable product requirements and prioritize additional features. This approach also simplifies the process of incorporating collaborative partners when necessary.



So what's next?

  • Backlog Items - incorporate additional features and optimization methods. I have those listed in the Planner backlog above.
  • GitHub package - Detailed implementation coming in GitHub
  • Additional automation suggestions - Recently, Microsoft announced an upcoming change to the security posture regarding Teams Resource account creation (MC780743). While this change may seem controversial, it is ultimately designed to enhance security and align with other tenant and account creation roles. Some of my esteemed colleagues have started discussing this topic and have ideas to address this challenge using similar automation concepts. For more information, follow Carl Karawani and Martin Heusser
I need to drop a plug for CoPilot(s) here - GitHub CoPilot and the power of AI make the process much more achievable.

Thanks to my peer Joe Andreshak for helping out with a few challenges !!! 

What automation challenges might your organization need to solve ?


No comments:

Post a Comment

Getting Started with Teams Queues App: Features, Voice Application Policy Settings, and Roles

Welcome to the world of Microsoft Teams Queues App! This powerful tool is designed to streamline your team's communication and enhance p...