Find Microsoft Accounts on Company Domains

Kevin CrouchAzure, How-To, Microsoft, Powershell, ScriptingLeave a Comment

The other day I was helping someone over in the WinAdmins Discord. Their users kept getting confused about what their passwords were, and it was causing a lot of HelpDesk tickets. Let’s find out what users have Microsoft accounts on the company domain so we can help move those accounts elsewhere to streamline the user experience.

Identifying the Problem

This prompt is the main source of the user’s confusion; the email address is the same for the user’s Work/School account and a Microsoft account. When an app supports signing in with both a Work/School and Personal account, it prompts the user for which type of account they want to use. Most users don’t know what the difference is, or where the Microsoft account came from.

Screenshot showing a choice between work / School account and Personal / Microsoft Account

As that link in the screenshot says, you can Rename the personal Microsoft account, but how can you know which users have a conflicting Microsoft account?

Designing a Solution

To find these conflicting Microsoft accounts, you can create a custom application that will only allow Microsoft accounts – if you try to use an email that doesn’t have a Microsoft account, it will just throw back an error that no MS account could be found.

This screenshot shows that a microsoft Account sign in prompt will return a warning if you give it an email address with no Microsoft Account associated

We can leverage this, along with login hints, to scale this up and make a scriptable solution to find any domain emails that have a Microsoft account conflicting with their Work account.

At this time, I don’t know of a way to prevent Microsoft accounts on the company domain, or automatically move them – but we can at least find the conflicts. This will allow the Help Desk to contact the end-user and help them relocate the personal account.

Setting up your App Registration

To set this up, we need to head to the Azure Portal and create a new app registration

Navigate to portal.azure.com, search for App Registrations, and select New Registration

We need a name for the consumers to see if they authorize our test application. I used: ContosoMicrosoftAccountVerifier

For supported account types, we cannot use the first three options because they all support tenant/company logins, but the fourth type will serve our purposes.

We cannot support account types from regular tenants, and instead only support Personal / Microsoft Accounts

We do not need a redirect URL for this setup.

Next, we need to setup a few aspects of the application, to use for dummy information.

Under API Permissions, we need to add a permission of some sort for it to request access to. The least amount of permissions was just the Profile permission.

select the minimum amount of permissions that you can. They should never be signed into anyway

Even though people should not be logging into our App, we need to setup some sort of Authentication for the App to theoretically use, even though we won’t use it.

Under Certificates and Secrets, I created a New Client Secret. You do not need to save the key values

Create a Dummy client secret, for the Microsoft backend. you do not need to keep the key

Constructing our App Authorization URL

Next, we need to gather the information for our authentication URL.

  • Authentication endpoints
  • Application ID (Client ID in the URL)
  • Email Addresses to check
  • Scope for our API Permissions

We get most of these from our App’s Overview page, from the API Permissions tab, and combine those with some other parameters from the OAuth 2.0 code flow to get a URL similar to the one below

You can test this URL above live for yourself, or use your own app created with the process above. Just adjust the Client_ID to match your Application ID, and adjust the login_hint to match your user

Valid Microsoft Account
Providing a Valid Microsoft Account email continues to a Password Prompt
Note: the email address is recognized, and the prompt has switched to “Enter password”

No Valid Microsoft Account
Providing an invalid Microsoft Account email throws a watning that the Microsoft Account does not exists
Note: the email address is not recognized, and the prompt still shows “That Microsoft account doesn’t exist”

Scripting the verification Process

Below is a quick script I made to build a list of all the company emails and iterate through checking them.

#$emailAddresses = '[email protected]','[email protected]','[email protected]'
$emailAddresses = Get-EXORecipient -RecipientTypeDetails UserMailbox -PropertySets Minimum | select -ExpandProperty Emailaddresses | where {$_ -match "SMTP:"} | foreach {$_ -replace '^smtp:'} 

$ApplicationID  = 'bd53bb89-0cc1-4eb3-90b7-ba008b1f2a2c'
$scope          = 'user.read'

$results = [System.Collections.ArrayList]::new()
$emailAddresses | foreach -Begin { $i = 1} -Process {
    Write-Progress -Activity 'Checking Email Addresses for Microsoft Accounts' -CurrentOperation ("Checking {0} - {1}/{2}" -f $_,$i,$emailAddresses.Count) -PercentComplete ($i/($emailAddresses.count)*100)
    $UserURL  = 'https://login.microsoftonline.com/consumers/oauth2/v2.0/authorize?client_id={0}&scope={1}&response_type=code&state=23424&login_hint={2}' -f $ApplicationID,$scope,$_
    $response = Invoke-WebRequest -Uri $UserURL 

    $results.Add( 
        [psCustomobject]@{
            EmailAddress = $_
            HasMSAccount = $response -match '"HasPassword":1' 
            Result       = $response.StatusCode
        }
    ) | Out-Null
    $i++
} 
$results

Our app doesn’t have any server code. We only need to get to the pre-login experience to confirm whether an email address has a Microsoft account associated with it. This means that users don’t need to finish logging in and authorize the app, but if they do finish logging in, they will get a consent prompt like this.

If a user does sign into this app fully, they will be prompted to approve the permissions requested earlier
Note: Unverified is the default state, but you can verify your tenant to show your company’s name instead. Details here

Wrap up

With this app we made, we can verify whether any email address has a Microsoft account associated with it with an automated method that we can script against.

To test any email address manually, just remove the login_hint parameter from the URL and you can enter any email address to check it, even without their password.

https://login.microsoftonline.com/consumers/oauth2/v2.0/authorize?
    client_id=bd53bb89-0cc1-4eb3-90b7-ba008b1f2a2c
    &scope=user.read
    &response_type=code
    &state=23424

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.