Being an architect usually means that I do not usually take part in ongoing operational activities when an environment has gone live and therefore the days where I handle requests for new Azure AD account creations are supposed to be behind me but most of my fellow colleagues may know that this isn’t usually the case as there are plenty of scenarios where we still need to roll up our sleeves and perform activities such as provision accounts. Account provisioning should be managed by a proper ticketing system, but it may not be available for new greenfield environment builds that has not been transitioned to operations. What I’ve found over the years is that large projects that last upwards of a year or more can have a large volume of new account requests and a large set of unidentified accounts when it is ready to be transitioned from the project to sustainment team.
One of the ways I’ve tried to better manage, and track Azure AD accounts is through the use of Microsoft Forms and a Logic App that automates the process of creating user accounts through an approval process. Microsoft Forms provides an easy way to create a secure form for requestors to fill out and track the submissions, while Logic App allows me to create a flow that sends approval to a group of administrators, automates the creation of accounts, and sends notifications. I’ve found that this temporary solution has served very well for situations where I do not have a ticketing system and I only have access to Microsoft Azure and 365 licenses.
This blog post serves to provide steps for how to create the form and the automation, and I hope it will help others who might need an interim solution for account creation and management.
Create an Automation Account Runbook to Generate a Random Password
While it is possible to have the Azure AD step generate a password when creating an account, most of the environments I’ve worked in has had more stringent requirements so we will need to create an Automation Account Runbook to randomly generate a password to be used when creating the Azure AD account. I won’t be providing too prescriptive steps for creating the Automation Account Runbook but would like to provide enough information for its creation.
Create an Automation Account or reuse one that is already available. For this example, I am reusing an Automation Account to host the runbook that will generate a random password and return it back to, in our case, a Logic App:
The runbook code that generates the password can be found at my following GitHub repository: https://github.com/terenceluk/Azure/blob/main/PowerShell/Generate-Random-Password.ps1
To lock down the Automation Account so that it can only be access by the Logic App, we’ll turn on the System assigned identity in the Identity blade, which will allow us to grant permissions to the Logic App:
Creating the Microsoft Form
There are various ways to create a Microsoft Form such as navigating to https://forms.office.com or directly in Teams. For this example, I’ll be creating the form directly in a Teams team that I created for IT Requests as shown in the screenshot below.
Begin by clicking on the + sign, search for Forms, and then click on the Forms icon:
Provide a name for the form and click the Save button:
The new form will be displayed in the Teams tab. Proceed to edit the for and add the attributes you would like to collect. The form I created consists of the following fields:
- Authorizing Manager – For placing an entry into Microsoft Form’s record as to who authorized this account creation
- Requestor - For placing an entry into Microsoft Form’s record as to who requested this account creation (the submitter may not be the requestor)
- First Name – Will be used for the Display Name and Given Name in the Create user azure ad action.
- Last Name – Will be used for the Display Name and Surname Name in the Create user azure ad action.
- Location – Will be used for the Office Location in the Create user azure ad action.
- Job Title – Will be used for the Job Title in the Create user azure ad action.
- Department – Will be used for the Department in the Create user azure ad action.
- Company Name – For placing an entry into Microsoft Form’s record
- Office 365 License – For determining whether this user requires an Office 365 license
- Power BI License – For determining whether this user requires an Power BI license
- DevOps Access – For determining whether to grant this user to DevOps
- Date Required – For determining when this user account is required
- Start Date – For determining when this user starts
- End Date – For determining when this user account should expire
- New User Contact Email – For determining what email address should be used to contact this user
- New User Contact Number – For determining what phone number should be used to contact this user
- Requestor's Email Address (approved and denied notifications) – For determining email address the new account details such as login name and temporary password should be sent to
You can preview the form by clicking on the Preview button:
With the form created, proceed to close the form in editing mode by click on the Edit | <Form name> and click on the Remove option:
The message can be a bit misleading but the reason why we’re removing it is because it is currently in edit mode:
With the form removed, proceed to click on the + sign in the tab again:
Click on the form icon again:
We will now use the Add an existing form option to add the form we had just created:
The form will now be in Fill mode (non editing):
The form can be accessed via the Teams channel or directly through a link (both require authentication by default). To obtain the link, simply navigate to https://forms.office.com and sign-in to locate the form:
Open the form and click on Collect Responses:
You can configure the permissions for accessing the form as well as shortening the URL:
Obtain the Form ID
Our Logic App will be triggered when a form has been submitted and the way it identifies the form is through its From ID. To find this unique string, navigate to www.office.com, click on the top left corner tile button and then Forms:
The most recent for we created will be displayed but if the recent list contains other documents you have worked on that has pushed the form off the list then we can navigate to it by clicking on the team under My Groups:
Proceed to open the form by clicking on it then with the form displayed in the browser, copy the URL and locate the string after the id= string and copy it:
https://forms.office.com/pages/designpagev2.aspx?origin=OfficeDotCom&lang=en-US&route=GroupForms&subpage=design&id=C0f0hB4_iUiflasPUUMCT_1a5E1qzx9IgJMuQa0Fbb9UME5RSlhYWFNLODdDQ1lVUzhINlRVRzBNNiQlQCN0PWcu
We’ll be using this form ID shortly so save it somewhere that can easily retrieved.
Logic App Flow
Before I begin, I would like to go through the flow of the submission, approval, processing, and notification flow of the Logic App as shown in the following screenshot.
The flow of the Logic App goes as such:
Approval Process
- The Logic App starts when a response is submitted through the Microsoft Forms
- The next step is to retrieve the values of each parameter in the submitted response so we can use it in the later actions
- The Initialize Variable is used for generating HTML code that will be used to generate an email as Send an email (V2) no longer accepts HTML code
- An approval email is sent to the desired approvers
Approved Process
If the one of approvers has approved the new account request then:
- An automated account runbook that generates a random password will be started to generate a random password
- When the password is generated, the password will be retrieved
- An Azure AD account will be created with the form submission values and the password generated
If Account Creation is Successful
If the Azure AD account creation is successful then:
- Set the initialized variable at the beginning of the workflow to contain the contents of the email to be sent out
- Send the email with the accounts detail to:
- The person who authenticated and submitted the form
- The email address provided in the field: Requestor's Email Address (approved and denied notifications)
- The infrastructure team
If Account Creation is Unsuccessful
If the Azure AD account creation is unsuccessful then:
- Set the initialized variable at the beginning of the workflow to contain the contents of the email to be sent out
- Send a friendly email with the accounts detail to the person who authenticated and submitted the form and the email address provided in the field: Requestor's Email Address (approved and denied notifications)
- Send a failure email with the accounts detail to the the infrastructure team
- Terminate the job and set the status as failed so the logic app run will be label as failed rather than success so it is easier to troubleshoot
Denied Process
If the one of approvers has rejected the new account request then:
- Set the initialized variable at the beginning of the workflow to contain the contents of the email to be sent out
- Send a friendly email with the accounts detail to the person who authenticated and submitted the form and the email address provided in the field: Requestor's Email Address (approved and denied notifications)
Create the Logic App
Now that we gone through the flow of the Logic App at a high level and have the form to collect the user input created, proceed to create a new Logic App:
With the Logic App created, proceed to navigate to the Logic app designer:
Scroll down to the Templates section and create a Blank Logic App:
A new blank template will be discovered for steps to be configured:
Type in Microsoft Forms in the search field and click on When a new response is submitted:
Sign into the tenant to create a connection to Microsoft Forms:
Select Enter custom Value for the Form Id:
Paste in the form ID we copied previously:
C0f0hB4_iUiflasPUUMCT_1a5E1qzx9IgJMuQa0Fbb9UME5RSlhYWFNLODdDQ1lVUzhINlRVRzBNNiQlQCN0PWcu
Proceed to create a new step, type in Get response details Microsoft forms in the search field and select the action:
Paste in the previously copied form Id into the Form Id field and select List of response notifications Response ID for the Response ID field:
The next step is to create an Initialize variable step to create a variable that will store our HTML code so we can use it to generate a properly formatted email out to notify the recipient about the status of the account creation. Add a new step, search for Initialize variable and select it under Actions:
Provide the following for the variable:
Name: NotificationEmailBody
Type: String
Value: <Blank>
Proceed to create a new step, type in Send approval email in the search field and select the action:
Fill in email address for approval.
One of the differences between Send approval email and Send an email (V2) is that the Body will treat the content as HTML code so paste in the code that will generate an email with HTML content:
The email template I used for this notification was taken from Sandro Pereira’s blog post here: https://blog.sandro-pereira.com/2020/01/26/logic-apps-how-to-send-a-well-formatted-html-email-notification-with-office-365-outlook-connector/
I made some changes to it as I only needed the table for the report. The modified HTML code can be found at my following GitHub repo: https://github.com/terenceluk/Microsoft-365/blob/main/HTML/ApprovalEmail.html
Note that you will need to update the body with the parameters submitted in the form by using the Dynamic content:
The following is a sample of the approval email that will be sent to the approvers:
With the approval email step completed, we will now create a condition that will determine whether the request has been approved or rejected. Proceed to create a new step, select Built-in and type in condition in the search field and select the action:
On the Condition box, click inside the Choose a value box.
From the dynamic content list that appears, under Send approval email, select the SelectedOption property.
In the middle comparison box, select the is equal to operator.
On the condition's right side, in the Choose a value box, enter the text, Approve.
When you're done, the condition looks like this example:
With the condition configured, we’ll be configuring the flow where the account creation is approved so proceed to navigate to the True block, add an action, search for Create job, and select Create Job Automation Account:
Fill in the required fields:
Subscription: <Select the subscription containing the Automation Account>
Resource Group: <Manually enter Resource Group containing Automation Account>
Automation Account: <Select the Automation Account containing the Runbook>
Runbook name: <Select the Runbook with the PowerShell script that generates the password>
Wait for Job: Yes
Managed identity: System-assigned managed identity
At this point, we’ll need to configure the required permissions so that the Logic App requires to authenticate to execute the Automation Runbook. Open another browser tab so you do not lose the Logic App step configuration, navigate to the Identity blade and turn on System-assigned:
Next, navigate to the Automation Account, open the Access control (IAM) blade, click on Role assignments, click Add, Add role assignment:
Search for the Automation Operator role:
Select the Members tab, click on Managed identity and select the Logic App for the Azure AD user creation:
Successfully assigning the permissions will display the following in the IAM blade:
With the permissions assigned to the Logic App so it can successfully execute the runbook, we can now add a step to retrieve the generated password from the runbook. Proceed to create an action, search for Get job output and select Get job output Azure Automation:
Fill in the required fields:
Subscription: <Select the subscription containing the Automation Account>
Resource Group: <Manually enter Resource Group containing Automation Account>
Automation Account: <Select the Automation Account containing the Runbook>
Job ID: <Use the Dynamic content feature to add the Job ID>
Create a new step, type in Create user azure ad in the search field and select the action:
Sign in to create the connection to Azure AD, grant the permissions request for the Logic App:
The available attributes are available:
- Account Enabled
- Display Name
- Mail Nickname
- Password
- User Principal Name
- Given Name
- Surname
The fields from the form should be available as dynamic content to use:
A few customizations that will need to be added to the fields are as follow:
Mail Nickname: To maintain consistency, I prefer to have this value all in lower case
Password: This is provided by the previously executed runbook but I’ve noticed that the output adds \r\n to the password which would cause this step to fail so we need to remove the undesired characters
User Principal Name: As with the Mail Nickname, I prefer to have this value all in lower case
With the above identified, we’ll be using expression functions (https://learn.microsoft.com/en-us/azure/logic-apps/workflow-definition-language-functions-reference) to adjust the values for these parameters. Switch over to the Code view for the Logic App:
Edit the lines as highlighted in the screenshot below:
Mail Nickname:
"mailNickname": "@{toLower(body('Get_response_details')?['r9b9abc58c2fb468181b916528b9b97ad'])}.@{toLower(body('Get_response_details')?['r17ea325b22b044c2ba26346a3e98c787'])}",
Password:
"password": "@{replace(body('Get_job_output'),'\r\n','')}"
User Principal Name:
"userPrincipalName": "@{toLower(body('Get_response_details')?['r9b9abc58c2fb468181b916528b9b97ad'])}.@{toLower(body('Get_response_details')?['r17ea325b22b044c2ba26346a3e98c787'])}@contoso.onmicrosoft.com"
With the adjustments made, this is what the step would look like:
The next step will now fork out to two different paths as the Create user step can succeed or fail and we want to handle both. To create these two different paths, add two Set variable steps and configure one to should run after as being is successful and the other as has timed out and has failed:
When the step succeeds, we want to set the variable that we defined earlier with the body of the email we’ll send out to confirm the account has created and when it fails, repeat the same but with different content.
The success email will include a username, the temporary password, and with a table containing the form submission data:
The next step will use the Send an email from a shared mailbox (V2) to send a confirmation to the desired recipients:
You may notice that the variable for the failed user creation is a bit different than the success as it does not include the welcome message and I intentionally did this because we will be sending two different emails (one user friendly and one for IT) where the first part of the email is different:
With the body configured, proceed to create the email notifications to be sent out to the user and the IT team:
The last step is to add a Terminate action to set the status as failed because we this is not done then the Logic App run history will state the process as being successful:
The last part of the Logic App is to handle the process when the approval is rejected. Proceed to use the Set variable action to create the body of the email:
Lastly, create an action to send a denied notification email to the desired recipients:
This has been a very long post but I hope this can provide start of how you can set up an automated process with approval to create Azure AD accounts. I can think of many other improvements I’ll be adding in for the future and a few of them include:
- Using Microsoft Purview Message Encryption to encrypt the email with the password by using a keyword trigger
- Using PowerShell cmdlets to set attributes not configuration with the Create AD User step
- Adding user to a group that assigns licenses
Hope this has been helpful.