Using PowerApps to streamline Support Agent common tasks

Thomas Cannervall
Daniel Wellington Tech Stories
10 min readApr 20, 2020

Before starting, the purpose with this article is that you hopefully can get some ideas of how to automate some common tasks and how we have implemented it

Introduction

Daniel Wellington is a Swedish brand founded in 2011. Since its inception, it has sold over 11 million watches and established itself as one of the fastest growing and most beloved brands in the watch industry.

Most people know how influencer marketing helped us become a global company, but what many don’t know is how our use of technology made that possible.

The first system we developed enabled us to reach influencers across the globe at scale. Then, we created our own e-commerce platform to be able to speak to our customers the way we wanted, and we built a complex ecosystem with B2B, B2C, and marketing channels working together.

We develop our services and applications on the AWS cloud platform and make extensive use of all of its amazing serverless features, neatly matched with microservice based architectures.

Our design principle is serverless first. If serverless is not available or practical, containers are recommended, EC2 is legacy. JavaScript, PHP, and Go are some of our languages of choice.

As a global tech-company that has disrupted an entire industry, we are constantly learning and finding our own way of doing business. Our latest venture is to try and removing rdp and streamline our support agents experiences using PowerApps / PowerAutomate.

My own role in the company is Cloud Operations / System Administrator where I and my colleagues have a few different workloads such as

  • AWS workloads
  • Infrastructure for our ERP systems (Dynamics NAV / Business Central)
  • Our On-premise AD / Azure AD
  • ADFS
  • Windows workloads
  • Automations and security features in O365 / Azure

Regarding MFA and the former Global Admin requirement

For quite some time our company has been on the verge of requiring MFA for all of our “Office 365” users. However with a roll out of that magnitude, 2k+ users, there are some problems that becomes blockers. The biggest for us?

The requirement of a Global Admin role to enable, disable and reset MFA

Now you might have been following various user voices on this subject like these
(In the plans)
https://office365.uservoice.com/forums/273493-office-365-admin/suggestions/17429305-delegate-permissions-for-managing-mfa

(Planned)
https://feedback.azure.com/forums/169401-azure-active-directory/suggestions/10072839-allow-the-user-admin-role-to-enable-disable-mfa-fo

However if your main objective with reading this article is to find a solution to that, I can tell you right now that there are indeed two roles for this purpose which we will be using.

Authentication Admin
Priviliged Authentication Admin

The former allows password resets and more but can’t handle authentication for Global Admins
The latter can’t reset passwords but can reset and handle multifactor authentication even for Global Admins

So by assigning these roles (directly or through PIM) you should be good to go

Why did we decide to go with PowerApps / Power Automate?

Simply because it gives us means to gather various common tasks in one place. Our support Agents are managing multiple systems. We can connect the app both to our “on-prem” solutions in AWS by using On-Premise Data Gateway connector but also to Azure. I will touch on the On-prem connectors in the end of this article

We have looked into Windows Admin Center (WAC) which was promising but didn’t quite deliver what we needed

We used to (well we still do to many things) use bot commands to send various request from Microsoft teams into AWS. But as the requests became more complex so did the commands which increased user error rates.

Also in the beginning of the COVID19 outbreak, our bot stopped being able to respond through the bot framework API back to teams (note this has been fixed though). The functions worked but it was hard for the agents to understand if things worked or not. It increased the demand for another management type.

So the first thing we actually did was migrating our On-Prem MFA reset to Power Apps. But as I said, more on that later.
It was time to create a possibility to manage MFA using Power Apps.

All things I will write about here can be found around the internet to some extent. It may not be exactly this which is why I will summerize how we do it and what sources I have found that should be credited

Let’s get started!

Manage O365 / Azure MFA Using Automations, Power Automate and PowerApps

There is an excellent guide (allthough a little outdated) that I had as a guide when starting to look into this
https://ezcloudinfo.com/2019/02/01/delegate-resetting-azure-mfa-for-helpdesk-through-azure-automation-run-book-and-microsoft-flow/

End-Flow, sort of:

Prequisities:

  1. You need to create a new Automations Accounts in the Azure portal. For this you need a Azure Subscription. When Setting this up you will need to have rights to set-up Azure Run As accounts which means you will need to be App Administrator. You will also need Owner or Contributor on the Resource group
    https://docs.microsoft.com/sv-se/azure/automation/manage-runas-account
    It may be required to be Global Admin at some point
  2. You need to create an account that has Priviliged Auth Admin and/or Authentication Admin

Create the Azure Automation Account

First of all, coming from AWS I would compare Automation Accounts to Systems Manager. It may not be a complete 1 to 1 but they share a lot of features

  • Go to https://portal.azure.com and choose Automation Accounts
  • Choose Add
  • Enter the information
    Name: This is the Name of the Automation Account
    Subscription: What subscription in Azure you are using
    Resource Group: Either choose one or create a new
    Location: Location of the Automation account
    Make sure to activatie Create Azure Run As Account
  • Create a new runbook with Powershell as type
  • Now you can do this in various way. Either you split it into multiple runbooks, or you create a bigger one with split functions. I’ll leave that up to you. Here is an example of a PS script to “Reset-MFA” for a user
  • You can ofcourse use this to Disable or Enable MFA for users or get status etc.
  • In order for the Support Agent to be able to run the job, the agent should atleast have the Automation Job Operator Role in the Authentication Account. You can changes this in the Access control (IAM)

Some things to consider before moving on

At the moment you can, with the Run As Account, connect to your subscription. It would have been awesome to add possibility to use this to connect to msol and reset that way but it just isn’t

You are left with an account without MFA to run the command. Now what you could / should do is atleast put in some credential swapping. You can do this within the automation account on a schedule

I looked at this when setting it up
https://www.itprotoday.com/iaaspaas/handling-passwords-azure-automation-service-accounts

Here is the script we ended up with which runs on a weekly schedule

Likewise you should look into cert renewal for the Automation Run As Account

PowerAutomate and PowerApps

Ok so now that we have set up the automation account and applied proper permissions, let’s head over to Power Automate and PowerApps
In order to get all the outputs we need atleast three flows

  • A flow to invoke/create the Automation Jobs
  • A flow to get the status of the Automation Job
  • A flow to get the output of a Automation Job

I say atleast because it depends on how you construct your runbooks. If you have one runbook for all functions you are interested in, you are fine with three. Otherwise you will need additional flows for each function runbook (status and output can be the same).

Why do we need seperate flows for status and output you might ask. Flow supports waiting for Job to finish!

The way Automation job works is that if you trigger a job, that job will end up in an Automation Que. It can sit there for quite some time before starting. This means that the response to PowerApps may time-out before the command is executed / completed

To avoid request timeouts, we can use a timer inside powerapps and poll job status / job output (Asynchronus request) with a timer
If you are not using Powerapps then you could use Wait for job to finish.

Credit where credit is due. I looked at this great guide when looking into Asynchronus request and it’s almost identical to what we will be using below
https://www.lieben.nu/liebensraum/2019/11/using-runbooks-interactively-in-powerapps/

  • Create a new flow in Power Automate. You can use Instant from Blank option
  • Give it a Name and choose Power App as trigger
  • Add a new step and Choose Create Job (Azure Automation)
  • Input the information needed such as subscription, resource group, automation account, runbook name and choose wait for job — no
    Add parameters as values with Ask in PowerApps
  • Finally add a Respond to PowerApps (In this case we only respond with JobId)
  • The flows for Status and Output are very similiar but instead of runbook with parameters you input the jobid which will be requested in PowerApps

Now that we have our flows, let’s head over to PowerApps

You can build your app from a template style like for mobile or set-up dimensions yourself. Whatever meets your preferences.

For this example. You will need the following items

  • An input field (for user email to manage)
  • Button(s) to trigger request(s)
  • A Status label
  • A timer
  • An output “label”

To give you an idea, this is what ours currently look like (not really DW UX approved yet :) )

So as for what the different elements do then

On screen visible we reset some contexts

UpdateContext({UserEmailReset: true}); ← ResetEmailTextBox when swapping between screens
UpdateContext({UserEmailReset: false});
UpdateContext({mgmtType: true}); ← Reset Management selector dropdown
UpdateContext({mgmtType: false});
Set(runbookOutput,Blank()); ← Reset Output variable
Set(runbookJobId,Blank()); ← Reset Jobid variable
Set(runbookActive,false); ← Set Runbookactive to false
Set(runbookResult,Blank()) ← Reset Results

The button(s) has a visible validation which checks if the input is an email format or not. Like this

If(IsMatch(NameofEmailTextBox.Text,Match.Email),true,false)

The OnSelect for the buttons looks like this

Set(runbookResult,Blank());
Set(runbookOutput,Blank());
Set(runbookJobId,Blank());
Set(runbookActive,true);
Set(runbookJobId,NameOfPowerAppFlowCreateJob.Run(NameofEmailTextBox.Text,User().Email).jobid); ← Creating job and saving the jobid
UpdateContext({StartTimer:true}) ← Starts timer

The Status label has the following text (Gives user some feedback on what is happening)

If(IsBlank(runbookResult) && runbookActive = false,”Status”,If(runbookActive,”Please wait for request to complete…”,runbookResult))

The timer has the following OnTimerStart (Try to fetch Job Output)

If(runbookActive && Len(runbookJobId) > 5,Set(runbookOutput,NameOfPowerAppFlowGetJobOutput.Run(runbookJobId).joboutput))

It has the following OnTimerEnd (Fetching job status if it’s ongoing etc)

If(runbookActive && Len(runbookJobId) > 5,Set(runbookResult,NameOfPowerAppFlowGetJobStatus.Run(runbookJobId).jobstatus));If(runbookResult = “Completed” Or runbookResult = “Suspended” Or runbookResult = “Stopped”,Set(runbookActive,false))

The Output label simply references the runbookOutput

And that is it for the PowerApp. Now all you need to do is adding users that are allowed to use the app. Do note that they need the Job Operator role as previously explained

In our case we have it as an additional Tab within Teams aswell for quicker access.

Manage On-Prem resources in AWS using On-Prem Data Gateway, ALB, Lambda, SSM etc

In the beginning of this article, I mentioned that we are also using the management app to manage some “On-Prem” AD stuff like our On-Prem Azure MFA server and management of our different Navision instances and our AD users ofcourse.

We learned that we could use On-Prem Data Gateway to trigger internal ALBs (Application Load Balancer) in AWS while testing some Automations for our Navision instances. Because of this we can attach a lambda function to that ALB that handles all the inputs and responds to the app.
As you will see below we use SSM to do the remote powershell sessions in AWS side.

Overview “On-Premise” flow

Going forward

There is always good to have some improvements to think of looking ahead. Somethings I/we would want to solve are

  • The account used for resets. Even though we are swapping passwords, the best thing would be to be able to use an account temporary or adding an MFA element to the request to protect it. AFAIK it is not supported in Graph either and is even more limited.
    It might work with an application password but I have not found any command that allows passing that parameter in any connection string
  • On prem we can require MFA for requests, it would be nice to be able to do that through graph etc. Perhaps some PS coder out there knows how to do this in Azure
  • All our code is in CloudFormation in AWS, It would be nice to do the same in Azure Resource Templates (ARM) if possible but I do not know that much about it at the time of writing this

--

--

Thomas Cannervall
Daniel Wellington Tech Stories

Reliability Engineer / System Administrator working at Daniel Wellington Technologies