Microsoft Entra supports the conversation of external users in your directory to internal users while maintaining the same object ID, permissions and group memberships. This removes the previous need to delete the external users, recreate them as internal users, and re-configure permissions and memberships.
In this blog, I will show you how to convert external users to internal ones using the web portal and Microsoft Graph PowerShell.
Why convert external users to internal users?
Some common scenarios for converting external users in your directory to internal users include:
- To support acquiring new businesses, where a B2B relationship may have been pre-established.
- To support the internal hiring of existing external consultants.
- To support the merging of two organisations due to acquisition or a legacy tenant split scenario.
Fundamentally, you shouldn’t purposefully create external users in your directory to support these scenarios. The conversion to internal user function reduces administrative and technical effort in converting existing external users, thus reducing the impact on the end user.
How to convert external to internal users
Follow the below steps to convert an external user (or guest) to an internal user in your directory using the Microsoft Entra web portal.
1. Log in to entra.microsoft.com.
2. Expand Identity, then select All users > All users > your external user.
4. On the Overview tab, select Convert to internal user.
5. A new window will appear on the right-hand side of the screen. You will be asked to enter the user principal name and generate a password.
6. When you are ready, click Convert. Your user properties will then be changed to member, indicating the user is now internal.
Convert external users to internal users with PowerShell
The same result can also be achieved programmatically using Microsoft Graph PowerShell. Use the below PowerShell example to convert an external Entra ID user to an internal user.
$body = @{
userPrincipalName = "NEW UPN HERE"
passwordProfile = @{
password = "PASSWORD HERE"
forceChangePasswordNextSignIn = "false"
}
}
Invoke-MgGraphRequest -Method POST `
-Uri "Beta/users/ID OF EXTERNAL USER HERE/convertExternalToInternalMemberUser" `
-Body $body `
-ContentType "application/json"
I have also expanded on this a little and created a helpful function for easily converting external users to internal users.
function Convert-MgExternalUser {
<#
.AUTHOR
Daniel Bradley
ourcloudnetwork.co.uk
.DESCRIPTION
Convert external users in Microsoft Entra ID to internal users
.EXAMPLE
Convert-MgExternalUser -ExternalUser "externaluser#EXT#@contoso.com" -AccountName "New external user account name" -password "new password" -DefaultDomain
#>
[CmdletBinding()]
param(
[Parameter(mandatory=$true)]
[string]$ExternalUser,
[string[]]$AccountName,
[string[]]$password,
[string[]]$domain,
[switch]$DefaultDomain
)
#Grab default domain
If ($DefaultDomain.IsPresent){
$Domain = ((Invoke-MgGraphRequest -Method GET -Uri "beta/domains" -OutputType PSObject | Select -Expand Value) | Where {$_.isDefault -eq "True"}).id
}
#Check the external user and grab ID
$ExternalUser -match '^.*(?=(\#EXT#))' | Out-Null
$Normalised = $Matches[0]
$UserCheck = Invoke-MgGraphRequest -Method GET -Uri "/beta/Users?`$filter=startsWith(UserPrincipalName, '$Normalised') and userType eq 'Guest'" -OutputType PSObject | Select -Expand Value -ErrorAction Stop
IF ($UserCheck -eq $null){
Write-Output "Unable to find external user, please try again."
Return
}
#Create request body
$body = @{
userPrincipalName = "$AccountName@$Domain"
passwordProfile = @{
password = "$password"
forceChangePasswordNextSignIn = "false"
}
}
#Convert external user to internal
Invoke-MgGraphRequest -Method POST -Uri "Beta/users/$($UserCheck.id)/convertExternalToInternalMemberUser" -Body $body -ContentType "application/json"
}
Understanding the impact of converting a user
From initial observations, the object’s ID has remained the same, and as such, any group memberships and permissions will also remain.
If the external user is logged into the Teams desktop app and viewing the organisation they were invited to as an external user, they will see the following error. To resolve this, they must sign out of Teams, quit Teams, clear the cache, and then sign back in with their new user credentials.
This experience may be different for you as the convert to internal user function is in preview.
You might be tempted to only click Sign in to try signing in again. When I did find that, it pre-filled out the username box with the username created for the internal user conversion, but the sign-in still failed.
To get this to work, I had to quit Teams, clear the local Teams cache and sign back in. Once signed back in, my group memberships remained the same, and the discussions I created within Teams had removed the (guest) text prepended to my name.
All group memberships listed in the Microsoft 365 MyGroups portals remained the same as any shared documents and direct permission assignment in SharePoint.
What to look our for
Unfortunately, while the process is simple, it is not always plain sailing. Here are some considerations I have identified during this process:
Summary
Overall, this was a straightforward and time-efficient process to onboard an external user as an internal user in your directory. However, these are some important considerations to make in larger, more complex environments, and that is the impact of an internal member being added to your organisation that was once an external user with a limited scope of permissions.