Convert FSLogix profile to local profile

FSLogix, the defacto profile management solution for Azure Virtual Desktop, allows you to easily roam profiles between different Azure Virtual Desktops.

A solution to convert profiles to FSLogix profiles is available, but for the reverse, I couldn’t find anything.

In some situations, e.g. dedicated VDI’s, a local profile may perform better and reduce infrastructure complexity (no share required). Especially in larger environments with thousands of VDI’s the required performance of the profile share is very high.

I wanted to test converting / migrating back from FSLogix profiles to local profiles on a specific machine, which resulted in a simple PowerShell script that can be executed using Run Command or by an admin on the VM.

It mounts the profile of a given user, copies the data to the local VM, unmounts the profile (so the profile is not deleted!) and sets a bunch of registry keys to properly connect the local profile and disable FSLogix roaming on that VM for that user.

See GitLab

Ghost Mailusers

We had an odd case today that Msft support hasn’t fixed yet, but in case someone googles the error and finds this, I did find a workaround.

We had a MailUser object that was inactive (soft deleted), but couldn’t be permanently deleted using

Remove-MailUser -PermanentlyDelete -Identity $mailuser.ExternalDirectoryObjectId

The resulting error was:

This mail enabled user cannot be permanently deleted since there is a user associated with this mail enabled user in Azure Active Directory. You will first need to delete the user in Azure Active
Directory. Please refer to documentation for more details.

However, nothing was found in AzureAD (or deleted users/recycle bin), and nothing was present in our on-prem AD.

This user was deleted a long time ago, and now being rehired….but account creation was being blocked because the mail user was still claiming the email address of this user.

After some messing around, and not patiently waiting for Msft 1st line support to delete this corrupted MailUser, I discovered the RecalculateInactiveMailUser switch in the set-MailUser command.

Normally, you can’t modify the primary smtp / aliases of a soft deleted mailuser or mailbox….BUT, for some reason, if you supply RecalculateInactiveMailUser you can. So:

Set-MailUser -Identity $mailuser.ExternalDirectoryObjectId -EmailAddresses $newProxies -RecalculateInactiveMailUser

Worked fine! While

Set-MailUser -Identity $mailuser.ExternalDirectoryObjectId -EmailAddresses $newProxies

Failed with

The operation couldn’t be performed because object ‘270fc89f-0424-42d2-8f54-25796f74457b’ couldn’t be found on ‘DB8PR02A05DC001.EURPR02A005.PROD.OUTLOOK.COM’.

Inviting an external user to a PowerApp programmatically

Another week, another use case for Managed Identities in Automation Accounts!

The scenario today concerns a PowerApp and connected resources that should be shared with external identities, automatically of course. For each user this requires a guest account in the host / resource tenant, and a license. The license can be applied in the home tenant of the guest, or in your tenant.

Key points:

  1. Runbook that invites a user and adds the resulting guest account to a security group
  2. Security group gives access to the PowerApp and underlying (SpO) resources, and uses Group Based Licensing to license the guest for PowerApps and Sharepoint Online
  3. Logic App that is triggered by the PowerApp (trigger on create item in a sharepoint list), and starts the runbook
  4. When the invited user (guest) redeems the invitation, they are directed to a Sharepoint page first so Sharepoint syncs their profile. Otherwise, the PowerApp will not have access to any lists in Sharepoint Online as Guests are not synced to SpO until they access SpO directly.

I may demo the PowerApp, Logic App and Sharepoint lists at some point, but the main thing I wanted to share today is the Azure Runbook that creates the Guest invitation and adds the Guest to a security group using the Managed Identity of the Automation account, instead of service accounts or other pre-2021 solutions:

https://gitlab.com/Lieben/assortedFunctions/-/blob/master/invite-guestUser.ps1

License reports by a Managed Identity

Capitalizing on the huge advantages that managed identities in Azure offer, here’s another use case similar to the scheduled migration script that also uses it’s managed identity (and graph permissions) to autonomously run as an Azure Runbook without any credentials stored.

https://gitlab.com/Lieben/assortedFunctions/-/blob/master/get-licenseReportByDomain.ps1

The script will log in to Graph, retrieve all unique license types and how they are assigned to users, and will then email an HTML report (table) the the specified recipient, order by email domain.

Microsoft 365, Azure, Automation & Code