Some Microsoft Graph PowerShell SDK Cmdlets Lose Body Parameters

Issue Affects Directory API Cmdlets

restore deleted user account with the Microsoft Graph.

In a March 2025 article, I discuss how to use the Microsoft Graph PowerShell SDK to restore deleted user accounts. Two methods are supported: restore an account to its original state and restore an account and change its user principal name. This feature allows a restored account to have a new user principal name with an amended given name, surname, or domain.

The trouble is that a change made to several Microsoft Graph directory APIs to add optional body parameters that did not previously have a body. This had a knock-on effect (tracked here) for anything based on .Net (like the Microsoft Graph PowerShell SDK) because the underlying method had to be changed from one without a body parameter to one with a body parameter. This kind of change can break the process used to generate the Microsoft Graph PowerShell SDK, so body parameters are now excluded for cmdlets generated from the affected APIs until Microsoft can fix the underlying issue.

Restore Deleted User Accounts with a New User Principal Name

The problem surfaces in the Restore-MgBetaDirectoryDeletedItem cmdlet when it restores a deleted account with a new user principal name because the cmdlet uses a hash table containing details of the new user principal name to pass a request body in the body parameter. No body parameter means that the cmdlet loses its ability to give the restored account a new user principal name. The SDK bug is tracked here.

Versions of Microsoft Graph PowerShell SDK generated before the change took effect retain the ability to run Restore-MgBetaDirectoryDeletedItem -BodyParameter to restore deleted user accounts. The last version I used for this task is V2.25, but it’s possible that a subsequent version will work. I can say that the version of the cmdlet in the latest version of the SDK (V2.34) does not have the parameter, so a different approach is necessary. Fortunately, the workaround is easy: instead of Restore-MgBetaDirectoryDeletedItem, use the Invoke-MgGraphRequest cmdlet to run the Graph API request. Exactly the same hash table can be passed as a request body.

The Adjusted Code to Restore Deleted User Accounts with a New User Principal Name

The necessary adjustments are simple. Literally, it’s a matter of swapping out the call to Restore-MgBetaDirectoryDeletedItem and replacing it with two lines. The first is the URI to pass, pointing to the deletedItems endpoint with the object identifier of the account to restore. The second runs Invoke-MgGraphRequest to post the request body (hash table) to the endpoint. Here’s the code:

$DeletedUserUPN = Read-Host “Enter the User principal name of the deleted account”
$NewUserPrincipalName = Read-Host “Enter the new User principal name”

$Headers = @{}
$Headers.Add("consistencylevel","eventual")
$DeletedObject = Get-MgDirectoryDeletedItemAsUser -Filter "endsWith(UserPrincipalName,'$DeletedUserUPN')" -Headers $Headers -CountVariable OutCount

If ($DeletedObject) { 
  # Details for new user principal name
  $NewUPNDetails = @{}
  $NewUPNDetails.Add("newUserPrincipalName",$NewUserPrincipalName)
  $NewUPNDetails.Add("autoReconcileProxyConflict",$true)
  Write-Host "Restoring Object with new User Principal Name"
  $Uri = ("https://graph.microsoft.com/beta/directory/deletedItems/{0}/restore" -f $DeletedObject.Id)  
  $Status = Invoke-MgGraphRequest -Uri $Uri -Method Post -Body $NewUPNDetails
  If ($Status) { 
    Write-Host ("Account restored for {0} with UPN of {1}" -f $DeletedObject.displayName, $NewUserPrincipalName)
    # Update the primary SMTP address for the account with the new UPN
    Update-MgUser -UserId $deletedObjectId -Mail $NewUserPrincipalName
  }
} Else {
  Write-Host ("Can’t find the {0} deleted account" -f $DeletedUserUPN)
}

An Unfortunate Break

Just when it seemed safe to embrace the Microsoft Graph PowerShell SDK fully after last year’s shenanigans, something like this comes along, even for beta cmdlets. The SDK developers are blameless here. They are simply reacting to a change that took place elsewhere in the Microsoft development firmament. Unfortunately, removing the body parameter will break any script that calls one of the affected cmdlets. All you can do is test, and if you run into a problem, the fix is easy.


Support the work of the Office 365 for IT Pros team by subscribing to the Office 365 for IT Pros eBook. Your support pays for the time we need to track, analyze, and document the changing world of Microsoft 365 and Office 365. Only humans contribute to our work!

Leave a Reply

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