Back to script library
Entra / Microsoft 365 · Groups

Restore deleted Entra ID groups

A script to show how to restore deleted Entra ID groups (Microsoft 365 and security groups) using the Microsoft Graph PowerShell SDK.

Connect & set up

Run these once per session. All scopes are read-only unless the script makes changes.

Connect-MgGraph -Scopes Directory.Read.All, Group.ReadWrite.All -NoWelcome

Run it

The main script. Copy it, or download the .ps1 and run it from your console.

If ([Environment]::UserInteractive) {
Clear-Host
Connect-MgGraph -Scopes Directory.Read.All, Group.ReadWrite.All -NoWelcome
Write-Host "Script running interactively... connecting to the Graph" -ForegroundColor Yellow
$Interactive = $true
} Else {
Write-Host "Script can't be run non-interactively. Exiting..." -ForegroundColor Red
Break
}
# Check that we have the correct scopes
If ($Interactive) {
[string[]]$CurrentScopes = (Get-MgContext).Scopes
[string[]]$RequiredScopes = @('Directory.Read.All', 'Group.ReadWrite.All')
$CheckScopes =[object[]][Linq.Enumerable]::Intersect($RequiredScopes,$CurrentScopes)
If ($CheckScopes.Count -ne 2) {
Write-Host ("To run this script, you need to connect to Microsoft Graph with the following scopes: {0}" -f $RequiredScopes) -ForegroundColor Red
Break
}
}
[array]$DeletedGroups = Get-MgDirectoryDeletedItemAsGroup -All
If ($DeletedGroups.count -eq 0) {
Write-Host "No recoverable groups can be found - exiting"; break
}
$Report = [System.Collections.Generic.List[Object]]::new(); $Now = Get-Date
ForEach ($Group in $DeletedGroups) {
[datetime]$DeletedDate = $Group.deletedDateTime
$PermanentRemovalDue = Get-Date($DeletedDate).AddDays(30)
$TimeTillRemoval = $PermanentRemovalDue - $Now
If ("unified" -notin $Group.GroupTypes) {
$GroupType = "Security"
} Else {
$GroupType = "Microsoft 365"
}
$ReportLine = [PSCustomObject]@{
Group = $Group.displayName
Id = $Group.id
GroupType = $GroupType
Created = Get-Date ($Group.createdDatetime)
Deleted = Get-Date($Group.deletedDateTime)
'Permanent Deletion due' = Get-Date($PermanentRemovalDue)
DaysRemaining = $TimeTillRemoval.Days
}
$Report.Add($ReportLine)
}
$Report | Sort-Object DaysRemaining -Descending | Out-GridView -Title "Select groups to restore" -PassThru | ForEach-Object {
Write-Host "Restoring group $($_.Group) Id $($_.Id)"
Try {
$Status = Restore-MgDirectoryDeletedItem -DirectoryObjectId $_.Id
} Catch {
Write-Host "Failed to restore group $($_.Group) Id $($_.Id). Error: $($_.Exception.Message)" -ForegroundColor Red
}
If ($Status) {
Write-Host "Successfully restored group $($_.Group) Id $($_.Id)" -ForegroundColor Green
}
}
Attribution