NOTE: Big shoutout to Madebygps for this amazing project idea: Onboarder. This is my version adapted to this series.
This has been an exciting journey, so far we’ve set up OnPremise Server Infrastructure and Microsoft 365, now with the help of Azure, let’s modernize some of the processes for HR, specifically the Onboarding process.
Previously, HR would send an email to IT with the basic information for the new hires, then IT would manually create the Domain user on Active Directory, create the Microsoft 365 user (which will give access to Office 365 apps and Outlook for Email), add to the needed groups and so on.
What if there was a way in which HR could send an email and the Microsoft 365 account would be created automatically based on the information?
That’s our goal for today, an Automatic Onboarding levering Azure Logic Apps
Overview
Azure Logic Apps is a cloud platform where you can create and run automated workflows with little to no code. By using the visual designer and selecting from prebuilt operations, you can quickly build a workflow that integrates and manages your apps, data, services, and systems.
Workflow
For our Logic App the workflow will be the following:
When a new email from: teddy@beyondbaremetal.com to onboarding@beyondbaremetal.com with the subject: Onboarding arrives.
The Name, Last name, Position, and Personal email will be extracted from the email body.
A new Microsoft 365/Azure user will be created with the data previously collected.
The Usage location will be set to US.
A new Microsoft 365 Business Standard license will be assigned to the newly created user.
Based on the Position (previously extracted) the new user will be added to a Microsoft 365 Group (IT, HR, Finance, or Marketing).
A welcome email will be sent to the user’s Personal email containing:
Full name
Work Email address
Temporary Password
Position
A notification email will be sent to IT, containing:
Full Name
Position
Email address
IT will then set that data in a PowerShell Script to create the Domain user.
Configuration
Let’s get started by creating the Logic App and actions:
When a new email arrives:
This operation will trigger the flow when an email arrives and based on the following fields:
Subject: Onboarding
This will add a layer of security as Teddy (HR Manager), is the only one authorized to make the flow triggered and will need to specify the subject as well.
Then we will parse the Email Body from HTML to Text:
Now let’s capture the data: Name, Last name, Position and Personal email:
On the parameters let’s set the following input:
This will capture the Name from the email body.
trim(first(split(split(string(outputs('HTML_to_Text')), 'Name: ')[1], '\n')))
Rinse and repeat for the rest of the fields:
Last name:
trim(first(split(split(string(outputs('HTML_to_Text')), 'Last Name: ')[1], '\n')))
Position:
trim(first(split(split(string(outputs('HTML_to_Text')), 'Position: ')[1], '\n')))
Personal email:
trim(first(split(split(string(outputs('HTML_to_Text')), 'Personal Email: ')[1], '\n')))
Time to Create the User:
For this action, we will use the CreateUser operation, let’s set the parameters as follows:
Account Enabled: Yes
Display Name:
We will use the previously captured Name and Last name:
concat(outputs('GetName'), ' ', outputs('GetLastName'))
Mail Nickname:
We will use the previously captured Name:
replace( trim(first(split(split(string(outputs('HTML_to_Text')), 'Name: ')[1], '\n'))), ' ', '_' )
Password: Any temp password
User Principal Name:
We will concat the user’s Name with @beyondbaremetal.com:
concat( trim(first(split(split(string(outputs('HTML_to_Text')), 'Name: ')[1], '\n'))), '@beyondbaremetal.com' )
Given Name: We will use the previously captured Name
Surname: We will use the previously captured Last name
Job Title: We will use the previously captured Position
Now that the user is created, we want to assign it a license but Azure Logic Apps doesn't have a built-in action or trigger to assign Office 365 licenses directly, so we will need to perform some extra steps, we will leverage Microsoft Graph:
Get an authorization token:
Let’s first create an App Registration
Navigate to: Azure > App registrations > New Registration
Set Name as LicenseAssignment
For Authentication:
Accounts in this organizational directory only (Default Directory only - Single tenant)
For Certificates & secrets:
Let’s create a new secret:
Take note of the Value and Secret ID:
For API Permissions:
Make sure Grant admin consent for Default Directory is selected.
Provide the following permissions to Microsoft Graph:
Directory.ReadWrite.All
User.Read
User.ReadWrite.All (this will allow us to assign Licenses to the user)
On Overview take note of the Application Client ID:
Back to the Logic App, Let’s get an Authorization Token:
Create an HTTP action called HTTP-GetToken:
For parameters:
URI:
https://login.microsoftonline.com/8ddb1f21-a6e7-4059-bf41-a02552acf3fc/oauth2/v2.0/token
Method: POST
Headers: Content-Type / application/x-www-form-urlencoded
Body:
it should be in x-www-form-urlencoded format with the following fields:
client_id: retrieved from the previously created App Registration
client_secret: retrieved from the previously created App Registration on the Certificate and Secrets section
client_id=CLIENT_ID&client_secret=CLIENT_SECRET&grant_type=client_credentials&scope=https://graph.microsoft.com/.default
Set Usage Location
To assign a license we need to specify the Usage Location (In this case US):
URI:
Let’s retrieve the newly created User ID:
https://graph.microsoft.com/v1.0/users/@{outputs('Create_User')['body/id']}
Method: PATCH
Headers:
Authorization / Bearer
outputs('HTTP-GetToken')?['body']?['access_token']
- This will present our previously created token as <access_token>Content-Type / application/json
Body:
This will set the Usage Location for the user to US:
{ "usageLocation": "US" }
Assign License
We got authorization, retrieved the User ID, and set the Usage Location, we are ready to assign the license:
Before proceeding we will need to know which license to assign, in our case, we have Microsoft 365 Business Standard, we need to know the skuID.
Let’s set up a Rest API call with Postman:
Method: GET
https://graph.microsoft.com/v1.0/subscribedSkus
Headers: Authorization / Bearer <access_token>
We can see the skuID now for "skuPartNumber": "O365_BUSINESS_PREMIUM"
which is Microsoft 365 Business Standard
Back to the Assign License action:
URI:
https://graph.microsoft.com/v1.0/users/@{outputs('Create_User')['body/id']}/assignLicense
Method: POST
Headers:
Authorization / Bearer
outputs('HTTP-GetToken')?['body']?['access_token']
- This will present our previously created token as <access_token>Content-Type / application/json
Body:
{ "addLicenses": [ { "skuId": "f245ecc8-75af-4f8e-b61f-27d8114de5f3" } ], "removeLicenses": [] }
Add User to a Group:
NOTE: These are Microsoft 365 Groups which we haven’t studied yet but we will in future posts.
Now we can add the user to a Group, in this case, we will use the Switch action:
On: It will get the Position (previously captured)
For each case we will have the parameters equals to the department name for example IT:
Then we will create an action Add user to group:
User Id: we will use the previously created user Id
Group Id: Go to the group and look for Object Id
Rinse and repeat that we are done with all groups.
Send Welcome Email
For this Action, we will use an SMTP Relay Operation
Finally, we can send the new hire all their Microsoft 365 new account information:
To: we will set the Personal Email previously captured
Subject: Welcome New Hire!
Body:
We will use the Name and last name, set the email address, set a temp password, and use the Position.
Welcome, @{outputs('GetName')} @{outputs('GetLastName')}!
You email address is: @{concat(
trim(first(split(split(string(outputs('HTML_to_Text')), 'Name: ')[1], '\n'))),
'@beyondbaremetal.com'
)
}
Temp Password: ChangeMe123!!$$
Your position is: @{outputs('GetPosition')}
Create the Active Directory User
The Microsoft 365 user is created, this will give the new hire access to Microsoft 365 Apps and Email with Outlook, now what about the domain user?
Let’s create a parallel action after the Switch to send an email to the IT department:
Subject: New Hire Name and Last name (captured from the previous actions)
Body: Here we will set Full Name, Position, and Email, captured from the previous actions along with a short message to the IT department.
Testing
We just hired Neil Tran (Marketing Manager) so Teddy will send the Onboarding email:
Let’s go to the Logic App > Run History:
We see it succeeded, let’s open it to check better:
We can see all actions were completed successfully, in case any action fails we will get an error and its outputs.
We can verify Neil’s Microsoft 365 account has been created and the Microsoft 365 Business Standard license has been assigned:
Neil receives the Welcome Email on his personal Email:
Neil can log in successfully to neil@beyondbaremetal.com:
IT gets an email with the new hire information:
Keep in mind the email was sent to it@beyondbaremetal.com which is a shared mailbox and Karl (IT manager) has access to it
To create a new user we have the following PowerShell Script:
We will modify it with the new hire information and run it
This will create the Active Directory user account for the new hire and based on the position it will add it to the correspondent Security Group.
IT = IT-RO
HR\= HR-RO
Finance = Finance-RO
Marketing = Marketing-RO
# Define mapping of positions to OUs and security groups
$PositionToOU = @{
"IT" = "OU=IT,DC=beyondbaremetal,DC=local"
"HR" = "OU=HR,DC=beyondbaremetal,DC=local"
"Finance" = "OU=Finance,DC=beyondbaremetal,DC=local"
"Marketing" = "OU=Marketing,DC=beyondbaremetal,DC=local"
}
$PositionToGroup = @{
"IT" = "IT-RO"
"HR" = "HR-RO"
"Finance" = "Finance-RO"
"Marketing" = "Marketing-RO"
}
# Input details for the new user
$Name = NAME # Input the user's Name based on the Email
$LastName = LASTNAME # Input the user's Lastname based on the Email
$Position = POSITION # Input the user's Position based on the Email
$SamAccountName = NAME # Input the user's Name based on the Email
$Email = "$SamAccountName@beyondbaremetal.local"
$Password = "ChangeMe123!!$$" # Default password (should be changed upon first login)
# Validate the position and get the corresponding OU
if ($PositionToOU.ContainsKey($Position)) {
$OUPath = $PositionToOU[$Position]
} else {
Write-Error "Position '$Position' does not have a corresponding OU mapping."
exit
}
# Validate the position and get the corresponding security group
if ($PositionToGroup.ContainsKey($Position)) {
$GroupName = $PositionToGroup[$Position]
} else {
Write-Error "Position '$Position' does not have a corresponding security group mapping."
exit
}
# Create the new user
try {
$NewUser = New-ADUser -Name "$Name $LastName" `
-GivenName $Name `
-Surname $LastName `
-SamAccountName $SamAccountName `
-UserPrincipalName $Email `
-Title $Position `
-Path $OUPath `
-AccountPassword (ConvertTo-SecureString $Password -AsPlainText -Force) `
-Enabled $true
Write-Output "User $Name $LastName created successfully in OU: $OUPath"
# Add user to the corresponding group
try {
Add-ADGroupMember -Identity $GroupName -Members $SamAccountName
Write-Output "User $Name $LastName added to group: $GroupName"
} catch {
Write-Error "Failed to add user to group '$GroupName': $_"
}
} catch {
Write-Error "Failed to create user: $_"
}
Once received, Karl logs in to the BBM-DC01, modifies the Script, and runs it:
Success:
Neil Tran created
Neil Tran added to Marketing-RO
With this, the new hire is all set with Microsoft 365 and Domain accounts.
Conclusion
In this post we’ve streamlined the Onboarding process by leveraging Azure Logic Apps, we’ve shown the proposed workflow and configured it correctly by applying the needed actions for each phase (receiving the email, capturing the data, creating the user, assigning licenses, adding it to a group, sending a welcome email and sending a notification email to IT), by the end, the HR Manager was able to send an Onboarding email and the new hire received the information and was able to login successfully.
The next steps will be improving the Azure App with verifications on duplicate data and implementing an action for sending the PowerShell script to IT with all new hire information.
Stay tuned for more content.
Thanks for reading!
Link to the series 👉 https://beyondbaremetal.hashnode.dev/series/beyond-bare-metal-setup