Self service Microsoft Teams Auto Attendant administration

So you have multiple Microsoft Teams Auto Attendants, and before every holiday your help desk is slammed with requests to update the out of office date on all these. There are always 3rd party tools you can buy to help you out, but I like to see what’s possible to create yourself almost for free. We are going to create form users can fill out to update holiday opening hours and greeting for your Auto Attendants.

First we need an App Registration in This is to be able to read the audio file users are uploading as a greeting message.

Click ‘New Registration’

Give it a name and click ‘Register’

Take note of the Client ID and Tenant ID, you will need that in the PowerShell script further down.

Click ‘API permissions’, ‘Add a permission’ and ‘Microsoft Graph’.

Click ‘Application permissions’.

Select ‘Files.Read.All’.

Click ‘Grant admin consent…’.

Go to ‘Certificates & secrets’ and click ‘New client secret’. Give it a name and click ‘Add’.

Copy the value of the secret.

Now we need to register an Automation Account.

Click ‘Create’ and enter the needed info and click ‘Create’

Click ‘Go to resource’.

Now we need to import the Teams PowerShell module into the Automation Account, so go to ‘Modules’ and click ‘Add a module’.

Search for ‘Teams’ and click on ‘Microsoft Teams’.

Click ‘Select’.

Select ‘7.1’ as the ‘Runtime version’. This is because PowerShell 5.1 in Azure Automation does not like to read wav files. Click ‘Import’.

Go to ‘Variables’ and click ‘Add a variable’. Give it a name and paste the App Registration secret as the value. Click ‘Create’

Go to ‘Credentials’ and click ‘Add a credential’. Add the username and password of a Teams admin account, then click ‘Create’.

Go to ‘Runbooks’ and click ‘Create a runbook’.

Choose the following settings and click ‘Create’.

Here you paste the PowerShell script you can find below.

[Parameter (Mandatory= $true)]
[String] $autoAttendantName,
[Parameter (Mandatory= $false)]
[String] $HolidayName,
[Parameter (Mandatory= $false)]
[String] $StartDate,
[Parameter (Mandatory= $false)]
[String] $EndDate,
[Parameter (Mandatory= $false)]
[String] $GreetingText,
[Parameter (Mandatory= $false)]
[String] $GreetingFileID,
[Parameter (Mandatory= $false)]
[String] $Choice
### Teams AA Administration ###
### Version 1.0 ###
### Author: Alexander Holmeset ###
### Email: [email protected] ###
### Twitter: ###
### Blog: ###
$TenantId = 'xxxxxxxxxxxxx'
$ClientID = 'xxxxxxx'
$ClientSecret = Get-AutomationVariable -Name 'secret'
$Credentials = Get-AutomationPSCredential -Name 'admin'
connect-microsoftteams -Credential $Credentials
function Get-MSGraphAppToken{
Get an app based authentication token required for interacting with Microsoft Graph API
A tenant ID should be provided.
Application ID for an Azure AD application. Uses by default the Microsoft Intune PowerShell application ID.
.PARAMETER ClientSecret
Web application client secret.
# Manually specify username and password to acquire an authentication token:
Get-MSGraphAppToken -TenantID $TenantID -ClientID $ClientID -ClientSecert = $ClientSecret
Author: Jan Ketil Skanke
Contact: @JankeSkanke
Created: 2020-15-03
Updated: 2020-15-03
Version history:
1.0.0 - (2020-03-15) Function created
param (
[parameter(Mandatory = $true, HelpMessage = "Your Azure AD Directory ID should be provided")]
[parameter(Mandatory = $true, HelpMessage = "Application ID for an Azure AD application")]
[parameter(Mandatory = $true, HelpMessage = "Azure AD Application Client Secret.")]
Process {
$ErrorActionPreference = "Stop"
# Construct URI
$uri = "$tenantId/oauth2/v2.0/token"
# Construct Body
$body = @{
client_id = $clientId
scope = ""
client_secret = $clientSecret
grant_type = "client_credentials"
try {
$MyTokenRequest = Invoke-WebRequest -Method Post -Uri $uri -ContentType "application/x-www-form-urlencoded" -Body $body -UseBasicParsing
$MyToken =($MyTokenRequest.Content | ConvertFrom-Json).access_token
Write-Warning "Failed to get Graph API access token!"
Exit 1
$MyHeader = @{"Authorization" = "Bearer $MyToken" }
catch [System.Exception] {
Write-Warning "Failed to get Access Token, Error message: $($_.Exception.Message)"; break
return $MyHeader
$global:Header = Get-MSGraphAppToken -TenantID $TenantId -ClientID $ClientID -ClientSecret $ClientSecret
$AutoAttendantID = (Get-CsAutoAttendant | Where-Object{$_.Name -like "$AutoAttendantName"}).Identity
$autoAttendant = Get-CsAutoAttendant -Identity "$AutoAttendantID"
If($Choice -like "Audio"){
$uri = "$($credentials.username)/drive/items/$GreetingFileID/content"
$content = Invoke-RestMethod -Method GET -Headers $global:Header -uri $uri -OutFile c:\temp\greeting.wav
$content = Get-Content "C:\temp\greeting.wav" -asbytestream
$audioFile = Import-CsOnlineAudioFile -ApplicationId "OrgAutoAttendant" -FileName "greeting.wav" -Content $content
$GreetingPrompt = New-CsAutoAttendantPrompt -AudioFilePrompt $audioFile
if($Choice -like "Text"){
$GreetingPrompt = New-CsAutoAttendantPrompt -TextToSpeechPrompt $GreetingText
$StartDate = Get-Date $StartDate -Format "dd/MM/yyyy"
$EndDate = Get-Date $EndDate -Format "dd/MM/yyyy"
$MenuOption = New-CsAutoAttendantMenuOption -Action DisconnectCall -DtmfResponse Automatic
$Menu = New-CsAutoAttendantMenu -Name "$HolidayName Menu" -MenuOptions @($MenuOption)
$CallFlow = New-CsAutoAttendantCallFlow -Name "$HolidayName" -Greetings @($GreetingPrompt) -Menu $Menu
$dtr = New-CsOnlineDateTimeRange -Start $StartDate -End $EndDate
$Schedule = New-CsOnlineSchedule -Name "$HolidayName" -FixedSchedule -DateTimeRanges @($dtr)
$CallHandlingAssociation = New-CsAutoAttendantCallHandlingAssociation -Type Holiday -ScheduleId $Schedule.Id -CallFlowId $CallFlow.Id
$autoAttendant.CallFlows += @($CallFlow)
$autoAttendant.CallHandlingAssociations += @($CallHandlingAssociation)
Set-CsAutoAttendant -Instance $autoAttendant

Click on ‘Publish’ and ‘Yes’.

Now we need to create a Microsoft Form. Click ‘New Form’.

Create the form based on the screenshots below. We use the display name of the Auto Attendant to find the correct one in the script, so that’s what’s added to field number 1.

Now we need to add some branching.

You can choose to share this openly or with specific people/groups.

The last part of the puzzle is to create a Power Automate flow that is triggered by the form and kicks of Azure Automation.

Go to ‘Create’ and click ‘Automated cloud flow’.

Give it a name and select ‘When a new response is submitted’.

Follow along and create the same actions as in the screenshots below.

Copy this JSON Schema and paste in under ‘Schema’ in the next action.

    "type": "array",
    "items": {
        "type": "object",
        "properties": {
            "name": {
                "type": "string"
            "link": {
                "type": "string"
            "id": {
                "type": "string"
            "type": {},
            "size": {
                "type": "integer"
            "referenceId": {
                "type": "string"
            "driveId": {
                "type": "string"
            "status": {
                "type": "integer"
            "uploadSessionUrl": {}
        "required": [

Now we are done, so let’s test to see everything is working.

This is just one example of what’s possible to create a self-service solution for Microsoft Teams Auto Attendant. Another thing you could create is the possibility to change the weekly recurring opening hours or maybe add a new greeting.

12 thoughts on “Self service Microsoft Teams Auto Attendant administration

  1. Very cool.

    How do you control who can run it? By who can submit the form?

    Why do you use an App Registration and Credential?


    • Correct, the ones with access to the form.

      App registration to be get permission to read the files stored from the form in OneDrive. (The audio greeting file) credential to log on to teams PowerShell.


  2. Hello
    You talked about third party tools earlier on that could do exactly this, would you mind sharing what these are? I’ve searched high and low for a third party app and I haven’t come across any.
    Thank you in advance!


    • Hi,
      sorry but looks like i might have misunderstood the functionality of a product i saw. Landis Teams Attendant Console is for handling calls in a que your already in, not to manage the Attendant :-/ If not, would not hurt to check with Landis if they have something.


  3. Hi Alex, have you worked out how to edit an existing auto attendant audio greeting? I’ve got a local PowerShell script using c:\temp and tried to use flow and forms\power apps but getting stuck. It says it goes through OK but doesn’t actually change the audio file.


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s