Harvest Windows 365 Cloud PC’s based on days not used
People are using Windows 365 Cloud PC’s for all kinds of reasons. In some cases it’s only used for a period of time, but the licenses are still allocated to users. Before you know all Windows 365 Cloud PC licenses within your organization are in use and you have a hard time to figure out if licenses can be freed.
I created a solution that will check if Cloud PC’s are not used for a specific amount of days. When the minimum threshold in days is met, the Azure AD object extension attribute for that specific Cloud PC will be updated with the “Days since last sign in” datetime. When the Cloud PC reaches the harvesting threshold in days, it will be harvested by removing it’s primary user from the license- and provisioning group. An exclusion can be made by adding employees to a “VIP” group.
|My solution is based on working with on-premise security groups, but can easily be adjusted for cloud only environments. Assign Cloud PC licenses to security groups and check the name construction for the provisioning groups. The code can be found on my GitHub and can be run as runbook in Azure Automation. Be careful check variables and test it first!|
How it works
The solution can be devided into two phases. All actions during those phases will be logged and can be uploaded to a SharePoint online location. In my configuration I scheduled the script as an Azure runbook that will run once a week on Sunday.
First phase (check Cloud PC for harvesting)
- Get all Cloud PC’s that have the extension attribute set and check if they are eligible for harvesting.
- It will check the “Days since last sign in”, if it’s below the minimum threshold in days the Cloud PC’s extension attribute will be cleared.
- The harvesting threshold in days will be determined based on the datetime value in the extension attribute. When the threshold is met the assigned user will be removed from the Cloud PC license- and provisioning group.
- A Cloud PC will be skipped from harvesting when the Cloud PC’s primary user is member of the VIP group or is added to it later on. The extension attribute will be cleared if it was set previously.
- All Cloud PC’s that are harvested will be added to a CSV file and can be uploaded to a SharePoint online location.
Second phase (check if Cloud PC extension attribute must be set)
- Check all Cloud PC’s that are provisioned and not have the extension attribute set.
- When the “Days since last sign in” equals or is more than the minimum threshold in days and the assigned user is not member of the VIP group, the extension attribute will be set with the “Days since last sign in” datetime.
- It will check the Cloud PC’s enrollment datetime in days, when “Days since last sign in” is not found. When the enrollment datetime in days is equal or more than the harvesting threshold in days, a datetime will be constructed by using the minimum threshold in days and set as extension attribute value. This method is used to give new enrolled Cloud PC’s a cool down period.
A service principal that can be used with Microsoft Graph and a service account to remove users from security groups. Below the permissions based on least privileged.
- Device.ReadWrite.All (needed for updating the extensionAttribute)
- CloudPC.Read.All (to get all Cloud PC related data)
- Account with permissions to remove users from domain groups or Azure AD groups
- Account with permissions to upload data to for example SharePoint Online
Days since last sign in
The “Days since last sign in” can be optained with Microsoft Graph Cloud PC getRealTimeRemoteConnectionStatus. This is the only reliable parameter that can be used for Cloud PC’s to determine the last activity datetime of it’s primary user. It can only find sign in activities for the last 30 days, after that it will show ” Not applicable (N/A)”. Therefore I am using the extension attribute and the enrollment datetime to preserve the last activity datetime, so we can work with a harvesting threshold of 45 days.
The Azure AD device object extension attribute will be used to set the datetime value. This datetime will be used to determine if a Cloud PC is eligible to be harvested. In my case I used the extensionAttribute2.
There will always be a License Harvesting log file containing all steps being done. Those steps are also presented in the script output. When Cloud PC’s are actually harvested, a Harvested Devices csv file will be created. In my configuration the files are uploaded to a SharePoint online site.