MEM custom service desk portal with Power Apps and Power Automate

Organizations are always looking for methods to innovate and with Microsoft 365 there are so many options to retool and build applications end-to-end while gaining value from the investment. Service Desk is one example of how organizations can utilize technology within Microsoft 365 to build solutions to improve IT productivity and end user satisfaction. This month’s post focuses on creating a customized service desk portal for non-Intune admins to perform tasks on behalf of end users such as wiping or retiring a device.

With Power Apps I’m able to access different services from Microsoft 365.  For example the user image an name in the upper right corner of the app below are pulled in through a Office 365 data connector, more on that later…



  • MEM Intune
  • Power Apps
  • Power Automate
  • Microsoft Graph

Let’s get started

Power Automate

For the app we need to create three separate Power Automate Flows. These are very simple flows as they use inputs from the Power Apps app to run the flows using Graph calls from an HTTP action.

Get user devices

We need a Power Automate Flow that takes the email address input in the Power App we’ll create later on in this post and utilizes it to call Graph to query for user devices. In the Flow below add the PowerApps trigger and add an Azure AD get user action below it. Select the empty field and then select “Ask in Power App” from the dynamic content.

The HTTP action takes a graph query and uses the input from the Get user step to fill in the user ID and select certain fields to populate a Power Apps collection. We then parse the JSON to identify the schema of the retuned request and finally add a response action to isolate the array of data returned. The Response action is super important as is the schema (pasted below the Power Automate image). The Response schema isolates the array which is a subset of the schema from the entire graph call.

Array I used for the Response action which references the “Value” returned in the parse JSON action:

“type”: “array”,
“items”: {
“type”: “object”,
“properties”: {
“id”: {
“type”: “string”
“deviceName”: {
“type”: “string”
“enrolledDateTime”: {
“type”: “string”
“manufacturer”: {
“type”: “string”
“model”: {
“type”: “string”
“serialNumber”: {
“type”: “string”
“operatingSystem”: {
“type”: “string”

Wipe device

Wipe device is super simple, again we add a PowerApps trigger, however now we add a variable called deviceID and the value will come from the selected record in Power Apps. We then utilize the returned device in a Graph query to wipe the device.

Retire device

Similar to Wipe device, retire device is just a copy, again we add a PowerApps trigger. We then utilize the returned device in a Graph query to retire the device.

Power Apps

In Power Apps create a new blank canvas app and on the initial screen (e.g. screen 1 (default name)) add the content similar to the image below. I chose to make this tablet friendly so the user experience across all devices is the same.

The images below display what the application looks like when completed:

Data connectors

In the app, add data connections for the three Power Automate flows and Office365Users under the Data connections as shown below. The “Collection” is auto generated once the app is run, however the other connectors are needed for the Power App to run properly.

For the “image” and the label below it, I query office through the built in Office365 Power Apps connector (added above) and once the user email is entered, the user photo and full name are displayed. This helps identify the user and make the experience more personable.

The other labels are self-explanatory and feel free to add or modify whatever works well for your organization.

The important objects in the form below are the input textbox for the user email which is sent back to Power Automate to run the device query and display the device(s) in the gallery. The search button has the code to communicate with Power Automate.

We add the code below to the “onSelect” action for the search button. What it’s doing is clearing a collection (i.e. ClearCollect), then creating a new collection named “PowerAutomateResponse”, then calling the Power Automate flow through the data connector in the Power App (i.e. ‘PowerApp->HTTP,Getuser’). We then add .Run(TextInput1.Text) to ‘PowerApp->HTTP,Getuser’ to look like this: ‘PowerApp->HTTP,Getuser’.Run(TextInput1.Text) what this does is sends the email input via the text field to the Power Automate flow named “Get user devices”.

Next I create a variable named “JSONvar” where I take the data received for all the devices returned and convert it to JSON so Power Automate can use it. However in my case, I only care about the device ID so I only select the ID of the device via:


To pull the user image select the image and add: Office365Users.UserPhotoV2(TextInput1.Text) to the “Image” field under the DATA property for the object. To pull the user name select the label under the image and add: Office365Users.UserProfile(TextInput1.Text).DisplayName in the “Text” file under the ACTION property for the object.

Next we need to populate the gallery with the items returned. Select the Gallery and add PowerAutomateResponse (which is the name of the collection) to the “Items” field under ACTION property for the object.

That’s it for screen1, now to screen two.

Add another screen (e.g. screen2) to the app and add the following the canvas:

For the image and label, I just copied from screen 1.

  • For each label next to the label name, under the ACTION property add the following for the “Text” field: Gallery3.Selected.item. By item you should select from all the columns returned to the collection, e.g. Gallery3.Selected.deviceName or Gallery3.Selected.operatingSystem or, and so on. I have seven unique fields with unique collection column data.
  • Wipe and Retire device icon buttons call two unique Power Automate flows.
  • For the wipe button add the following to the “OnSelect” field under ACTION: Set(DeviceID,;(‘PowerApp->HTTP’.Run(DeviceID))
  • For the retire button add the following to the “OnSelect” field under ACTION: Set(DeviceID,;(RetireDevice.Run(DeviceID))

What I’m doing is setting a variable called DeviceID because I need to send the ID and only the ID from the selected item back to Power Automate, i.e. “Set(DeviceID,”. The string after this is a call to the unique Power Automate flow returning the DeviceID variable.

Feel free to add an additional prompt so there are no accidental wipes or retires.

Now onto the “Chat with user in Teams” button.

If I’m supporting a user I probably want to speak with them, so I decided to add a button that utilizes the user email we entered on the first screen (i.e. TextInput1.Text) and I deep link to Teams via a Launch command for the button. Add: Launch(Concatenate(“”,TextInput1.Text)) to the “OnSelect” field for the button under ACTION properties. I believe having chat capability using Teams rounds out the support experience in the app.

That’s it for the app. Feel free to modify as necessary to what works best for your org. Also, wipe and retire aren’t the only commands, I imagine there are lots of other uses for this type of portal.

Role based access

Since this is a portal for non-Intune admins we’ll want to set up proper RBAC roles and permissions in the endpoint manager console. Do this by navigating to and selecting “Tenant administration -> Roles -> All roles” and begin setting up permissions for your non-admin users. More details on RBAC may be found here:

Here’s a video of the Power App process

Full size video:


We created a simple service desk portal for non-Intune admins utilizing Power Apps, Power Automate, and Microsoft Graph. Take a minute to imagine the possibilities with these tools to further automate and create custom portals for admin and even end users.

%d bloggers like this: