So you’ve got Microsoft Teams and you’ve got some calling plans. You don’t have enough to give every user one, so you come up with a business process that lets you be selective based on business justification. How do you integrate that business process to make it easy for IT and your users to follow?

Traditionally, you’d maybe make a shopping cart item in your service management portal and instruct the user to go there and place an order. On submission, it would trigger an approval process and may be even a provision on approval action. But what if you don’t have this expensive solution? What if you want to extract the value out of your Microsoft 365 subscription?

Well you can do this very easily and without too much hard work. In the following example I am using a simple online form that a user can submit and on submission, trigger a bunch of events that will ultimately lead to them being provisioned a phone number in Microsoft Teams.

For this exercise, we need the following components readily available of any Enterprise Subscription in Office 365

  • Microsoft Forms – Used for the end user form
  • Microsoft Flow – Used as a business process and conditional trigger / action solution (like IFTTT, but better)
  • AzureAD – We need this for Azure Group Based Licensing (easier to manage)

In addition to these inclusive features of your Office 365 Subscription, we also need an Azure Subscription so we can use the benefits of Azure Automation Accounts. We use Automation Accounts to store Azure Runbooks which are scripts that are triggered by a job. We use Flow to trigger these jobs.

By the end of this article, you will have a basic, automated provisioning process template to build on. My job is to show you the way, and therefore devoid of any error checking, which in a production scenario you’d absolutely need.

The experience will be this:

  • User will access request form online, complete and submit
  • Request will be emailed to their manager who will then approve* or reject the request.
  • On approval, the user will be licensed with the correct Office 365 licenses and automatically assigned a phone number from the Microsoft Cloud
  • The user will get an e-mail upon completion confirming the action has been completed and their new phone number that has been allocated.
  • *if the manager rejects, the user will get a rejection email

Creating Your Automation Account & Scripts

Head on over to the Azure Portal ( and make sure that you have a valid subscription.

Go to Azure AD and create two AzureAD Security Groups (assume you know Azure Group Based Licensing):

  1. Teams Standard Phone User
  2. Teams International Phone User

In the standard user group assign the base O365 license e.g. E3 or E5 with Phone System and your domestic calling plan. In the international group assign the base license and your international calling plan, or communication credits.

Note down the Group Object ID of each of these groups. You’ll need them soon.

In the search bar type: automation accounts

This will take you to the Account page. Click the Add+ button and create an automation account (best to choose same data center location as your tenant)

Next, in the automation account you have just set up, click on the credentials blade and add a credential that will have the privileges to run your scripts. Give it a friendly name e.g. “Cred” (Change Scripts with correct name)

Now we need to load the required modules into the automation account. Open the modules blade and click on browse gallery

Search for the AzureAD Powershell Module

Add this module to your automation account. Next we need to load the SkypeOnline PS Module. This is not available in the gallery. Assuming you have this installed somewhere on your PC you will need to ZIP the contents of the SkypeOnlineConnector folder located in c:\program files\common files\skype for business online\modules folder.

Now that you have zipped this folder, upload it as a module to the modules blade in the automation account by clicking on Add a Module. You should see it become available after around 10 minutes.

Now click on the Runbooks blade and create 3 runbooks:

  1. For Licensing the User
  2. For Checking Provisioning Status of User
  3. For Provisioning the User

Make sure both runbooks are PowerShell runbooks

You should have 3 blank runbooks created now like this

Now load the scripts into each runbook.

Open the Licensing User and Paste the following code in, replace as necessary (remember those Azure AD Licensing Group GUIDs? You need them now).

Save the runbook and publish it.

Now open the ProvisionCheck runbook and paste the following code in. Again replace as necessary. This script basically checks Skype continuously until provisioning has completed. We need this to halt the number assignment until we can actually implement it.

Save the Runbook and Publish.

Finally Open the TeamsPhoneUser Runbook and paste the activation code in

Save the Runbook and Publish.

That’s it for Azure Automation, now the fun stuff can begin.

Create the Form

Head on over to Microsoft Forms ( and create yourself a form. In my example here we have a simple form that asks the following questions:

  • What is your sign in address (UPN)
  • What Site Are You Normally At (Dropdown)
  • Who is Your Manager
  • Do you Need International Calls
  • What is Your Justification Reason

My form looks like this:

How you create your form, and how you word your questions will affect the flow, so for this example I recommend that you use the same wording as I have.

Now for the Flow..

Creating the Flow

Ok now before we go into Flow and start doing stuff, lets just recap what we need to do. We need to do something on Form submission, so this is the entry point into the flow.

Next we need to get the contents of the form so we have some data to use. Without it we are stuffed.

We then need to invoke and approval workflow that gives someone the authority to approve or reject the request. Then on either action we need to carry out the approvers commands

One of two things are going to happen at this point. If the approve approves the request, the flow will kick off all the cool stuff and provision the user. If they reject, the requestor is going to get a rejection email.

Now go to Microsoft Flow and create a flow.

Add your entry point by adding an action and searching for Microsoft Forms. Select Forms, then select Triggers and select “When a new Response is Submitted. Then choose the form Id

Now we need to apply the flow actions to each submission. Add a action and search for “Apply to Each”, then Select the Output “List of Response Notifications”

Inside this control we are going to house all our actions. Now we need to get the form content, so we search for forms again and then choose “Get Response Details”. Select the Form Id and select the Response Id from the menu

Now add another action, search for “start and approval”. In this example its a single user approval (their manager). Compile the approval email as you need. You can insert values from the form for clarity to them, like this:

Note I used the Managers email field from the form as the assigned to address so that they get the email.

Now we need a condition to decide what to do if we get an approval or rejection back. Add a action and search for “Condition”.

Add in the Response from the approval and what the expected value is e.g. “Approve”

Now you’ll get a Yes and No branch. The no is what to do if the response is not Approve. In this example, we are just going to send and email to the requestor.

In the No Branch add an action and search for “send email”. Fill out the email with the information you can pull from the submitted form e.g. the requestor UPN and any other information you want.

Step check, take a breather and when minimised you should now see this

Now for the Yes Branch.

The first thing we need to do is call our automation runbook for licensing the user with the appropriate requirements for calling. Add an action and search for “automation” choose Azure Automation and select Create a Job

Select your Azure Subscription, Resource Group and the Automation Account we created. Now select the Runbook LicenseUser. You should see it is asking for two input parameters. Choose the Email Address of the requestor from the form as the UPN and for International Calling the result from the International Calling Question in the Form, like this

The next step is we need to sit and wait for licensing and back end provisioning to complete before we can actually assign a number to the user. If we try now, it will fail. It can take up to 24 hours for this to work, so what do we do? This is where the second runbook comes in. It checks the users Skype and Teams licensing and back end provisioning repeatedly every 10 minutes until all the expected assigned plans have been provisioned. Only then will it return a value which we can then action on.

Create a new Azure Automation Job, doing the same as before, this time choosing the ProvisioningCheck Runbook

From this runbook, we are expecting something back and we need to tell Flow we are expecting something and what to do with it. Add an action and search for Azure Automation, choose “Get Job Output”. Here we are getting the job id of the previously submitted job so we can pull the output from it.

Now the putput from the job is in JSON format, so we need to tell flow to parse JSON. Add an action and search “Parse JSON”. The content will be the Content from the Azure Job and we need to tell flow content type and properties to expect in the content. In the schema enter the following.

We are expecting a JSON Object back, the “Status” is the property we are expecting back from the script and the content of that property is a string value.

"type": "object",
"properties": {
"status": {
"type": "string"

Progress check. You should now have these actions under the Yes Branch

Now we need to add a condition. The condition is if the property “Status” is equal to “Ready” then go ahead and provision, If not send an email to IT Support telling them of a flow fail. Add this condition.

Now under the No Branch add a send email like before and this time send it to your IT Support desk

Now to the Yes branch, what do we want to do if the result is set to Ready?

Add an action and create a new Automation Job this time calling the TeamsPhone Provisioning Runbook and supplying the UPN and Location of the user from the form

Now again, we are expecting a result back from this job. It will contain the UPN of the user and the phone number we allocated them. So add another action to get the job output

Again, the format of the output is JSON, so we need to parse it to send an email to the requestor informing them of their new number. Add a parse json action and use the following schema

"type": "object",
"properties": {
"upn": {
"type": "string"
"phone": {
"type": "string"

The last action we need to do is send an email to the requestor informing them that their request has been approved and completed. Add an email action and place the phone property in the email body like so

The complete flow should look like this

Seeing It All In Action

User can now go to the form and complete. On submission, their manager gets an approval email

As the manager I click Approve and I am told that my response has been submitted

In Flow I can see that my flow completed

If I check Azure Automation I can see my Runbook Jobs Completed

If I want I can click in to each one and see the output

If I go into the Teams Admin Center, I can see if the user has been provisioned with this number

The user will receive their email like this:

And that is it. Seems quite complex when you write in a blog, but its very straighforward and only takes a hour if that to set up (longest bit was writing the simple scripts).

Obviously you can take this as far as you want. But for a simple self service phone number assignment tool, it does the job!


One thought on “Self Service Phone Number Assignment in Microsoft Teams with Automated Provisioning”

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.