Mar 01 2023 04:19 PM
Contributors:
Juan José Guirola Sr. (Next Generation Endpoint GBB for Americas)
Bobby Chang (Power Platform GBB for Americas)
Enterprises of all sizes are adopting and aligning Windows 365 to solve several business-critical scenarios. Organizations appreciate the simplicity of the solution, rapid deployment, and enhanced end user experience; offering the opportunity to include new solutions to their services catalog!
Part of the simplicity of Windows 365 is that its management plane is Microsoft Intune. Leveraging the Windows 365 admin blade in Intune, administrators can perform the initial configuration of the service and perform on going monitoring of Cloud PCs deployed within the enterprise with several reports being made visible through the “Reports” blade, to include Device management, Endpoint Security, Endpoint Analytics, etc. We have recently introduced a new type of analytical report – Cloud PC utilization report (preview) – which brings visibility to Cloud PCs with low usage. This is a nice addition to the platform, and a much-needed report.
For some organizations, that level of reporting will suffice. But if you are looking for a more custom report that aligns to the specific goals and needs of your organization, then keep reading. This blog will describe how to use the Microsoft Power Platform to automate the reporting of Windows 365 based on your specific criteria and receive notifications via email when the criteria is met.
In our example, we are setting the criteria to report on Cloud PCs that have not been logged on to for 60 days or more. Let’s get started.
The following items are required to automate the process and deploy in a production environment: (For personal development and sandbox/testing scenario, you can use the Microsoft 365 Developer Plan and Power Apps Developer Plan).
Azure App Registration with the following permissions: CloudPC.Read.All. For enterprise production scenarios, we would recommend leveraging the Application Lifecycle Management (ALM) capabilities in Power Platform, in order to safely adopt future changes to your processes. However, this is outside of the scope of this blog post.
If you have followed our previous BLOG – How to automate Windows 365 Cloud PC self-service requests – you may have already performed these steps. If so, please proceed to the next section of this BLOG.
Register MS Graph as an Enterprise application in Azure Active Directory.
Figure 1: A screenshot of the Azure Active Directory blade in the Azure services portal.
Figure 2 : A screenshot of the Register an application screen, showing the details that need to be identified for the new application.
Figure 3: A screenshot of the recently created application overview with the Application (client) ID and Directory (tenant) ID details highlighted.
|
Figure 4: A screenshot of the Select permissions setup.
In this section, we will build the Power Automate flows that will orchestrate the Last Login monitoring reporting process. This decision flow illustrates the end-to-end process of retrieving Cloud PC attribute values from the Microsoft Graph leveraging the Windows 365 API and parse through the LastLoginResult value to compare against our criteria of 60 days or more.
Figure 5: A flowchart depicting the process for reporting Cloud PC Last Login.
To begin, sign into Microsoft Power Automate with your Microsoft 365 organization credentials.
Figure 6: A screenshot that shows the Recurrence trigger.
At this point, we need to determine the automated actions, based on the “LastLoginResult” value of the Cloud PC. This can be accomplished by parsing through each Cloud PC LastLoginRestult value and applying a “Condition” action.
Let’s add a GET step to the flow to gather Cloud PC attribute value:
https://graph.microsoft.com/beta/deviceManagement/virtualEndpoint/cloudPCs? $select=userprincipalname,id,displayName,managedDeviceName,Status,imageDisplayName,lastModifiedDateTime,lastRemoteActionResult,lastLoginResult
Figure 7: Example setup for Graph API controls to gather Cloud PC attribute value.
Figure 8: A screenshot of completed content and schema details for Parse JSON.
{
"type": "object",
"properties": {
"@@odata.context": {
"type": "string"
},
"value": {
"type": "array",
"items": {
"type": "object",
"properties": {
"userPrincipalName": {
"type": "string"
},
"managedDeviceName": {
"type": "string"
},
"id": {
"type": "string"
},
"displayName": {
"type": "string"
},
"imageDisplayName": {
"type": "string"
},
"status": {
"type": "string"
},
"lastModifiedDateTime": {
"type": "string"
},
"lastRemoteActionResult": {},
"lastLoginResult": {}
},
"required": [
"id",
"userPrincipalName",
"displayName",
"imageDisplayName",
"managedDeviceName",
"status",
"lastModifiedDateTime",
"lastRemoteActionResult",
"lastLoginResult"
]
}
}
}
}
Note: You can also get this schema by using the Graph explorer to request from the same endpoint. Use the Generate from example button to generate the schema.
Figure 9: Compose control example.
https://graph.microsoft.com/beta/deviceManagement/virtualEndpoint/cloudPCs/@{items('Apply_to_each_2'...']}? $select=userprincipalname,id,displayName,managedDeviceName,Status,imageDisplayName,lastModifiedDateTime,lastLoginResult
Example:
Figure 10: Example setup for retrieving lastLoginResult value for each specific Cloud PC.
{
"type": "object",
"properties": {
"@@odata.context": {
"type": "string"
},
"value": {
"type": "array",
"items": {
"type": "object",
"properties": {
"userPrincipalName": {
"type": "string"
},
"managedDeviceName": {
"type": "string"
},
"id": {
"type": "string"
},
"displayName": {
"type": "string"
},
"imageDisplayName": {
"type": "string"
},
"status": {
"type": "string"
},
"lastModifiedDateTime": {
"type": "string"
},
"lastRemoteActionResult": {},
"lastLoginResult": {}
},
"required": [
"id",
"userPrincialName",
"displayName",
"imageDisplayName",
"managedDeviceName",
"status",
"lastModifiedDateTime",
"lastRemoteActionResult",
"lastLoginResult"
]
}
}
}
}
Figure 11: A screenshot of the Parse JSON schema.
Figure 12: lastLoginResult Condition Expression.
At this point we are ready to add logic to the flow based on meeting the criteria of the condition.
If yes -
split(variables('lastLoginResult-Value'),'"')
outputs('Compose_3')?[3]
div(sub(ticks(variables('DateNow')),ticks(variables('Composed_LastLoginResult_Value'))),864000000000)
Now that we’ve been able to extract the proper number of days since lastlogin, let’s send out the email notifications.
Figure 13: Sample email template.
Once you’re past the Apply to Each scope,
The entire flow process should look like the image below.
Once you’ve completed adding in steps to your automation flow, you’re ready to test the solution. You can run a manual test or wait till the schedule task kicks off. Finally, you should receive an email like the one below:
NOTE:
WE WILL UPDATE THIS ARTICLE IN THE NEAR FUTURE TO INCLUDE THE ADDITION OF UPDATING A TABLE IN POWER APPS AND A FRONT FACING APPLICATION WHERE ADMINS CAN TAKE ACTION TO RECLAIM WINDOWS 365 LICENSE! STAY TUNED!!!
Continue the conversation by joining us in the Microsoft 365 Tech Community! Whether you have product questions or just want to stay informed with updates on new releases, tools, and blogs, Microsoft 365 Tech Community is your go-to resource to stay connected.
Mar 20 2023 11:47 AM
Mar 20 2023 02:33 PM