Physical Address
304 North Cardinal St.
Dorchester Center, MA 02124
Physical Address
304 North Cardinal St.
Dorchester Center, MA 02124


Let’s imagine a company that uses Microsoft 365 for all its day-to-day operations. One day, the global administrator account is hacked. The hacker blocks access to all other administrator accounts, including the “Break Glass Account” protection account. The company then loses full access to its Office 365 tenant. This is an extremely serious situation. Not only can the company no longer access its data and services, but the hacker also has access to all the company’s sensitive information.
For all this, a hacked Microsoft 365 global administrator account is extremely serious and can have disastrous consequences for an organization.
Regular steps to recover your Office 365 tenant:
Contacting Microsoft and recovering the account can take time, and in our case every minute counts.
That’s what we’re going to discuss today.
Of course, to be able to recover a Microsoft 365 tenant, you need to prepare a backup access way. I’m not talking here about a “Break Glass Account”, because even that account can be blocked by the hacker after taking control and you can’t log in again.
The solution I’m going to present today is an Entra ID application managed from Microsoft Graph, this application will allow you to add Global Admin accounts at any time and recover your access and block the compromised account even if you’ve lost access to all the admin accounts of your Microsoft 365 tenant.
1 – Create an Entra ID application with specific rights for account creation and role assignment.
2 – Create a Self-Signed certificate and install it in the local certificate store, then keep the certificate in a safe place.
3 – Export the certificate to the Entra ID application and use it as a means of authentication.
4 – Connect to this application using PowerShell and Microsoft Graph, then perform a Global admin account creation test.
5 – Keep this application as a backup to recover an Office 365 tenant in case a Global Admin account is compromised.
Open Microsoft ISE As Administrator from the windows button :

then copy paste this code :
# Test if Microsoft.Graph Module is installed, if Not Install it
IF (-not (Get-Module -Name Microsoft.Graph -ListAvailable))
{
Write-Host "BEGIN - Install Microsoft.Graph Module " -ForegroundColor Green
install-Module Microsoft.Graph -Force -AllowClobber
Write-Host "Module Microsoft.Graph Installed ....................................... OK" -ForegroundColor Green
}
else
{
<# Action when all if and elseif conditions are false #>
Update-Module Microsoft.Graph -Force
Write-Host "Module Microsoft.Graph Updated ....................................... OK" -ForegroundColor Green
}
# Test if MSAL.PS Module is installed, if Not Install it
IF (-not (Get-Module -Name MSAL.PS -ListAvailable))
{
Write-Host "BEGIN - Install MSAL.PS Module " -ForegroundColor Green
# Install module MSAL for powershell
Install-Module MSAL.PS -Scope AllUsers -Force
Write-Host "Module MSAL.PS Installed ....................................... OK" -ForegroundColor Green
}
else
{
<# Action when all if and elseif conditions are false #>
Update-Module MSAL.PS -Force
Write-Host "Module MSAL.PS Updated ....................................... OK" -ForegroundColor Green
}
# Import Module MSAL for Authentication
Import-Module MSAL.PS
Execution Result :


Still in the same PowerShell ISE window , copy paste this code :
#============================== Connect to MG ===========================
# Connect to microsoft graph
Connect-MgGraph -Scopes "Application.ReadWrite.All"



Check your Client ID + Tenant ID…etc
Still in the same PowerShell ISE window , copy paste this code :
# Get ClientID + TenantID + Scopes + Authtype +Account + ...
Get-MgContext

Switch to Profile v1.0 :
Still in the same PowerShell ISE window , copy paste this code :
# Switch to profile v1.0
Select-MgProfile -Name "v1.0"
In our case, I’m going to call the application “RecoveryApp1”. You can use any other name to disguise your application.
Still in the same PowerShell ISE window , copy paste this code :
# Create New Az Application
$NewAzApp = @{
DisplayName = "RecoveryApp1"
Web = @{
RedirectUris = "https://localhost:8080"
ImplicitGrantSettings = @{
EnableAccessTokenIssuance = $true
EnableIdTokenIssuance = $true;
}
}
}
New-MgApplication @NewAzApp
Execution Result , application created successfully :

You can find out new application directly in ENTRA ID :
From Entra ID -> App Registration -> RecoveryApp1


Still in the same PowerShell ISE window , copy paste this code :
# 1 - Get new Az App created recently
$AzApp = Get-MgApplication -Filter "DisplayName eq 'RecoveryApp1'"
$AzApp
# 2 - Create Secret for Az App
$AzAppSecret = Add-MgApplicationPassword -ApplicationId $AzApp.Id
Execution Result :

You can Check created Secret from here :
Entra ID -> App Registration -> RecoveryApp1 -> Certificate & Secrets -> Client Secrets

from Microsoft Azure open the “RecoveryApp1” application then go to the “API Permissions” section

Select “Microsoft Graph“

Select “Application Permission“

Select to Add this roles to your App :




Now we need to authorize these rights for our Application.
Select “Grant admin consent” buton the confirm with “YES”

Now you should see granted permissions like this :

Still in the same PowerShell ISE window , copy paste this code :
#splatting for human readability
$CertParam = @{
'KeyAlgorithm' = 'RSA'
'KeyLength' = 2048
'KeyExportPolicy' = 'NonExportable'
'DnsName' = 'localhost'
'FriendlyName' = 'GraphApi-BackupApp1'
'CertStoreLocation' = 'Cert:\CurrentUser\My\'
'NotAfter' = (Get-Date).AddYears(10)
}
#Creating self signed cert with parameters from above.
$Cert = New-SelfSignedCertificate @CertParam

Here I have Created Temp Dir on “C:\Temp“
Still in the same PowerShell ISE window , copy paste this code :
# Export Certificate to Desktop the upload it to Azure AD :
Export-Certificate -Cert $Cert -FilePath C:\Temp\GraphApi-BackupApp1.cer

These steps will guide you efficiently through the process of downloading a certificate for your Entra ID application on Microsoft Azure.
To download an Entra ID application certificate, follow these red-numbered steps:


Keep in mind, after using Self-Signed Certificate, you need to store it in secure location like an Password Manager or flash drive which can be used in an emergency (I recommand to use Two copy on two flash drive in case the first one doesn’t work properly)… Same thing with Tenant-ID and Application-ID
For flash drive you can use anyone with write Lock protection, I’m using this one (You can find it on Amazon or any other market):
Kanguru SS3™ Flash Drive w/ Physical Write Protect Switch
Still in the same PowerShell ISE window , copy paste this code :
# Disconnect from Microsoft Graph
Disconnect-MgGraph

We’ve now finished preparing the Graph application for our Microsoft 365 tenant.
We’re now going to test the connection by creating a Global admin account.
After preparing the Entra ID application, the following code is the most important one to save with all the information I’m about to mention.
All the previous part won’t be used anymore, but you’ll need this code every time you’ve lost access, so keep it in a safe place with the certificate you exported in the previous part if you ever change PC, install the certificate again and run the following code.
This step is usually used after you’ve lost access to your tenant, but we’ll do a test run now to make sure our script works. You can log in infinitely and create so many global admin accounts each time.
Before you start, you’ll need to prepare a few items of information:
To retrieve the tenant ID and the application ID, you can go directly to the Entra ID application and copy/Paste it.

Here you need to replace variables on the first section with your own informations, then you can execute the code :
# ======================= First Section ==========================================
# Complete Tenant ID + Application ID
$TenantId = "wae9b7bd-q237-787f-eae9b7bd"
$AppId = "eae54326-8787-4f7f-2124rt45"
# Replace Account Name + Domaine
$DisplayName = "Backup Admin"
$MailNickName = "Backup.Admin"
$UserPrincipalName = "Backup.Admin@domaine.onmicrosoft.com"
$Passwd = "P@ssw0rd@!"
# ======================== Second Section =========================================
# Connect to MG Application registred earlyer using loacl generated certificate
# Get full path Certificate with Thumbprint
$CertificateThumb = "Cert:\CurrentUser\My\" + (Get-ChildItem "Cert:\CurrentUser\My\" | Where-Object FriendlyName -EQ 'GraphApi-BackupApp1').Thumbprint
# Get certificate that we gonna use for connection
$Certificate = Get-ChildItem $CertificateThumb # PSChildName
#Connect to Graph using access token
Connect-MgGraph -TenantId $TenantId -AppId $AppId -Certificate $Certificate
#============================== MG Create New User =======================
$PasswordProfile = @{
ForceChangePasswordNextSignIn = $false
ForceChangePasswordNextSignInWithMfa = $true
Password = $Passwd
}
New-MgUser -AccountEnabled -DisplayName $DisplayName -MailNickname $MailNickName -UserPrincipalName $UserPrincipalName -PasswordProfile $PasswordProfile
#============================== Assign Global Admin Role to New User =====================
$userUPN = $UserPrincipalName
$roleName = "Global Administrator"
$role = Get-MgDirectoryRole | Where-Object {$_.displayName -eq $roleName}
if ($null -eq $role)
{
$roleTemplate = (Get-MgDirectoryRoleTemplate | Where-Object {$_.displayName -eq $roleName}).id
New-MgDirectoryRole -DisplayName $roleName -RoleTemplateId $roleTemplate
$role = Get-MgDirectoryRole | Where-Object {$_.displayName -eq $roleName}
}
$userId = (Get-MgUser -Filter "userPrincipalName eq '$userUPN'").Id
$newRoleMember =@{
"@odata.id"= "https://graph.microsoft.com/v1.0/users/$userId"
}
New-MgDirectoryRoleMemberByRef -DirectoryRoleId $role.Id -BodyParameter $newRoleMember
# Get all properties for New Microsoft Graph User
Get-MgUser | Where-Object UserPrincipalName -EQ $userUPN | Select-Object *
Here is the result of my code execution, new user created :

We can check our new Global Admin User directly from Azure, keep in mind in case of recovery you won’t have access to Azure.


1 – Open new in-private browser and go to : https://login.microsoftonline.com/

2 – Type new account credantials, in my case : Backup Admin

you can then block the compromised account to recover it later after changing the password.
Losing access to an Microsoft 365 tenant as a result of a hack is a very serious situation that can have disastrous consequences for a business. It is essential to take preventive measures to secure administrator accounts and to put in place contingency plans to respond to such incidents. the procedure we’ve seen allows us to avoid waiting times with Microsoft and surveys that can take up a lot of your time.
Finally, this incident underlines the importance of good security hygiene, including the use of two-factor authentication, regular employee training and the constant updating of security policies.
Thanks