Delete Azure AD User Accounts and Restore Them Afterwards with the Microsoft Graph PowerShell SDK

Service Principal is Latest Critical Azure AD Object to Support Recovery

According to message center notification MC344406 (18 March), in early April Microsoft plans to roll-out the capability of recovering deleted service principal objects. Service principals are critical parts of registered Azure AD apps, such as the apps used to execute Microsoft Graph API queries with PowerShell. They’re also used in Azure Automation accounts, the Microsoft Graph PowerShell SDK, and managed identities. In all cases, the service principals hold the permissions needed for an app or account to operate. The worldwide roll-out to all tenants should complete by late May.

When the capability is available, any time an administrator deletes a service principal (for instance, because a registered app is no longer needed) using the Azure AD admin center, PowerShell (using Remove-AzureADServicePrincipal), or the Microsoft Graph API, Azure AD will place the service principal into a soft-deleted state. This already happens today for user, group, device, and application objects.

Deleted Azure AD objects stay in the deleted items container for 30 days. When the retention period elapses (extending to maybe a few days afterwards), Azure AD proceeds to permanently delete the object.

During the retention period, administrators can restore an object, which makes it easy to recover if someone deletes an important item by accident. For now, the list deleted items API doesn’t support service principals, but it will after the roll-out. Figure 1 shows user objects in the deleted items container as viewed through the Graph Explorer.

Viewing deleted Azure AD user accounts via the Graph Explorer

Delete Azure AD user account
Figure 1: Viewing deleted Azure AD user accounts via the Graph Explorer

Using Old Azure AD Cmdlets

MC344406 features two cmdlets from the Azure AD Preview module:

In some respects, it’s odd that they use cmdlets based on the Azure AD Graph API because Microsoft has scheduled the Azure AD modules for retirement at the end of 2022.

Of course, apart from the licensing management cmdlets, the rest of the Azure AD cmdlets will continue to work after retirement, which makes it perfectly acceptable to specify the cmdlets now, especially if replacements in the Microsoft Graph PowerShell SDK are unavailable.

Using Microsoft Graph PowerShell SDK Cmdlets with Deleted Azure AD User Accounts

The Microsoft Graph PowerShell SDK can be difficult to navigate. It’s composed of 38 separate sub-modules. Although cmdlets are gathered logically, it can still be hard to find the right cmdlet to do a job. As you’d expect, the current version (1.9.3) doesn’t appear to include cmdlets to handle soft-deleted service principal objects. For now, we can see how to perform common administrative actions with user accounts as a guide to what should be available for service principals.

With that in mind, here are the steps to soft-delete user accounts, list the accounts in the deleted items container, and hard-delete (permanently remove) an account.

Soft-Delete an Azure AD User Account

To soft-delete an Azure AD account, run the Remove-MgUser and pass the object identifier or user principal name of the account to delete. The cmdlet does not prompt for a confirmation and deletes the account immediately:

Remove-MgUser -UserId Sue.Ricketts@office365itpros.com

List Soft-Deleted Azure AD User Accounts

During the 30-day retention period in the deleted items container, you can recover the account from the Azure AD admin center or by running the Restore-MgUser cmdlet. Before we can run Restore-MgUser, we need to know the object identifiers of the objects in the deleted items container. This code:

  • Uses the Get-MgDirectoryDeletedItem cmdlet to fetch the list of deleted user accounts (instead of passing an object identifier, we use the special microsoft.graph.user term to tell Azure AD that we want a list of user accounts). The Property parameter can be ‘*’ to return all properties of the deleted objects, but in this case, I’ve chosen to limit the set of properties to those that I want to use.
  • Loops through the data returned by Azure AD to extract the properties we want to use. The different behaviour of the Azure AD cmdlets and the Microsoft Graph PowerShell SDK cmdlets is an example of why tenants need to plan the upgrade and testing of scripts which use the Azure AD cmdlets.
  • Lists the soft-deleted user accounts.
$DeletedItems = Get-MgDirectoryDeletedItem -DirectoryObjectId microsoft.graph.user -Property 'Id','displayname', 'deletedDateTime', 'userType'
[int]$n = $DeletedItems.AdditionalProperties['value'].count
If ($n -eq 0) { 
   Write-Host "No deleted accounts found - exiting"; break }

$n = $n-1
[int]$i

$Report = [System.Collections.Generic.List[Object]]::new()

For ($i = 0; $i -le $n; $i++) {
    $Command = "$" + "DeletedItems.AdditionalProperties" + "['value'][$i]"
    $Item = Invoke-Expression $Command
    $DeletedDate = Get-Date($Item['deletedDateTime'])
    $ReportLine = [PSCustomObject][Ordered]@{ 
           UserId   = $Item['id']
           Name     = $Item['displayName']
           Deleted  = $DeletedDate
           "Days Since Deletion" = (New-TimeSpan $DeletedDate).Days
           Type     = $Item['userType'] }
    $Report.Add($ReportLine)
}
$Report | Sort {$_.Deleted -as [datetime]} | Format-Table UserId, Name, Deleted, "Days Since Deletion", Type -AutoSize 

UserId                               Name                      Deleted             Days Since Deletion Type
------                               ----                      -------             ------------------- ----
92cef396-1bd3-4296-b06f-786e2ee09077 The Maestro of Office 365 19/02/2022 17:36:44                  31 Guest
c6133be4-71d4-47c4-b109-e37c0c93f8d3 Oisin Johnston            26/02/2022 18:13:26                  24 Member
2e9f1189-d2d9-4301-be57-2d66f3df6bb1 Jessica Chen (Marketing)  04/03/2022 11:52:48                  18 Member
8cd64635-bce6-4af0-8e64-3bebe354e9a4 Alex Redmond              05/03/2022 17:36:45                  17 Member
0f16501c-8302-468a-99a6-78c22b0903d2 Jennifer Caroline         18/03/2022 21:33:13                   3 Member
3a6116ab-0116-490e-bd60-7e0cd9f36c9d Sue Ricketts (Operations) 20/03/2022 19:53:29                   2 Member
4a25ccf0-17df-42cf-beeb-4fd449531b47 Stephen Rice              22/03/2022 19:30:06                   0 Guest

Remove Soft-Deleted Azure AD User Account

To remove a soft-deleted directory object, run the Remove-MgDirectoryDeletedItem cmdlet and pass the object identifier. Like Remove-MgUser, the cmdlet doesn’t ask for confirmation and permanent deletion happens immediately.

Remove-MgDirectoryDeletedItem -DirectoryObjectId f9d30b84-ad5f-4151-98f0-a55dafe30829

Time of Transition

We’re in a time of transition now as Microsoft does its best to retire the Azure AD modules and build the capabilities (and hopefully the documentation) of the Microsoft Graph PowerShell SDK. In the intervening period, any time you see an example using Azure AD cmdlets, try to convert it to use the SDK. It’s a great way to learn.


Keep up to date with developments like the Microsoft Graph PowerShell SDK by subscribing to the Office 365 for IT Pros eBook. Our monthly updates make sure that our subscribers understand the most important changes happening across Office 365.

Leave a Reply

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