Powershell/Graph : locating cloud only users

If you are in a hybrid AD domain which is defined as servers running the ADDS (Active Directory Domain Services) role then you are regarded as hybrid regardless of the DC's location.

Local Domain < > Entra

In this particular example, we have a domain called bear.local Which all our workstations and servers are joined to, and we also synchronize those objects to Entra.

This synchronization process is done with the utility called Entra Connect, or the previous name for the utility was AD-Connect, then, furthermore, if you want to go back in the time machine, this also used to be called DirSync.

If you still have an active directory domain, then you need to use this utility to sync accounts and objects and other attributes from Active Directory into Entra.

Why not create in Entra?

If you have both a ADDS Domain and an Entra one, Some people will obviously just want to create groups and users and devices in Entra.

Unfortunately, this can have negative effects when you complete these actions because the same object cannot exist into different domain services.

Let’s say I create a computer account called Fuzzybear.bear.local and then I go ahead and create a user called FuzzyClaws.bear.local - these accounts only exist in Entra and not ADDS - and this appears to work for the short term until we move onto the next section.

Overridden objects/users and Incompatibilities

If you have this particular set up where you have accounts/devices in Entra that are invisible to ADDS, the problem that occurs if someone creates that same user in ADDS - when this happens all will remain normal and it will appear like you’ve got the same account in both ADDS and Entra.

That is until the synchronization step runs happens by default every 30 minutes, then as ADDS will be the primary source of information because you’re in hybrid mode the accounts that have created in Entra will be overwritten with the information from ADDS.

This will usually mean you will have two accounts one has been marked as a duplicate and the primary one that’s coming from ADDS, However, depending on your synchronization rules that account in Entra Will either be moved to deleted accounts or magically renamed to something else.

Users and distribution groups

This one is where it can get quite interesting, If all your distribution groups are served by ADDS And then synchronized to Entra - This means you are not able to add that User successfully to the distribution group if it uses local exchange - as there is no record in ADDS for that user if you search for them, you will not get a result to add.

Furthermore, if you’re in hybrid mode for ADDS there will be a strong chance you’re also in hybrid mode for Exchange, if this is the case, you will also find if you have this peculiar set up, you will have another abnormality - this will occur when you send a job through exchange locally that then send messages on to exchange online.

The people in this position with cloud only accounts will fail to get all these messages. You’re sending with that method however people that have been set up with a synchronized ADDS account will get those emails.

Think about consistency and supportability

If you were just creating an account using Entra For some scenarios that may not be catastrophic however you have to think of the bigger picture before you apply the lease administrative effort, and just create those accounts in the cloud without giving a second thought to processes that require ADDS (this includes directly and indirectly)

How do you find these cloud only users?

Excellent question, that is where this post started, but sometimes the background is more important than the solution.

Obviously, you are not able to search for accounts that are not synchronized with ADDS, You have to apply a little more logic than that.

We are not interested in any guest accounts As these would never be in ADDS, likewise, we are also not interested in accounts that do not have a company name set to our own, that would indicate they are in the identity ExternalAD accounts.

Entra Portal Search

This is the search we are trying to replicate with Powershell, as you can see it contains all the variables we require and it lists 45 users meetings those requirements:


The Script : CloudOnlyUsers.ps1

# Ensure you have the Microsoft Graph module installed
#Install-Module Microsoft.Graph -Scope CurrentUser -Force

# Connect to Microsoft Graph
Connect-MgGraph -Scopes "User.Read.All"

# Get all users (or a manageable subset)
$allUsers = Get-MgUser -All -Property "id,displayName,userPrincipalName,onPremisesSyncEnabled,creationType,companyName"

# Filter the users in PowerShell
$filteredUsers = $allUsers | Where-Object {
    $_.onPremisesSyncEnabled -eq $false -and
    $_.creationType -ne 'Invitation' -and
    $_.companyName -like 'Severn*'
}

# Display the results
$filteredUsers | Select-Object DisplayName, UserPrincipalName, OnPremisesSyncEnabled, CreationType, CompanyName

# Display the count of the filtered users
$filteredUsersCount = $filteredUsers.Count
Write-Output "Total Cloud only users: $filteredUsersCount"


That will then output all the users and give you a count which means the script is consistent.


Deleting those Cloud Users

If you wish to delete these users add this code to the bottom of the previous code, this will delete them with a confirm, if you wish to turn this off then update variable in bold.

# Delete the filtered users
foreach ($user in $filteredUsers) {
    try {
        Remove-MgUser -UserId $user.Id -Confirm:$true
        Write-Output "Deleted user: $($user.DisplayName) ($($user.UserPrincipalName))"
    } catch {
        Write-Output "Failed to delete user: $($user.DisplayName) ($($user.UserPrincipalName)) - $($_.Exception.Message)"
    }
}

Previous Post Next Post

نموذج الاتصال