Blog Post

Exchange Team Blog
3 MIN READ

Deprecation of Exchange Online PowerShell UserPhoto cmdlets

The_Exchange_Team's avatar
Oct 16, 2023

As announced via Message Center (MC678855) on the 2nd October 2023, we are deprecating the Exchange Online PowerShell UserPhoto cmdlets and transitioning customers to the Microsoft Graph PowerShell SDK.  This deprecation is a part of a broader initiative to streamline a coherent user profile image experience by consolidating user profile photo requests to the Microsoft Graph service, allowing a more reliable profile photo experience, addressing issues with inconsistent sizes and formats, and enabling faster refresh of profile photos across the Microsoft 365 product suite.

Starting in April 2024, tenant admins will no longer be able to use the Exchange Online PowerShell UserPhoto cmdlets to Get, Set, and Remove user profile photos. Note that these cmdlets will remain functional in Exchange Server (on-premises).

Tenant admins can perform the same actions through the Microsoft Graph PowerShell SDK to Get, Set, and Remove user profile photos, or alternatively can administer the user photos through Azure Active Directory or the Microsoft 365 admin center as detailed in this article.

Refer to the table below, containing both Exchange Online PowerShell and Microsoft Graph cmdlets to locate the ones you need in Microsoft Graph PowerShell SDK.

Exchange Online cmdlet you might use today

Microsoft Graph cmdlet you should start using

Microsoft Graph cmdlet notes

Import-Module ExchangeOnlineManagement

Install-Module Microsoft.Graph

Documentation

Connect-ExchangeOnline -UserPrincipalName <userId>

Connect-MgGraph

For authentication info see documentation

Set-UserPhoto -Identity <userId> -PictureData <pictureData>

Set-MgUserPhotoContent -UserId <userId> -InFile <inFile>

UserId: OID/SMTP/UPN

Permissions: owner calls (User.ReadWrite), non-owner calls (User.ReadWrite.All)

InFile: string path to the file to upload

Documentation

Set-UserPhoto -Identity <groupId> -PictureData <pictureData> -GroupMailbox

Set-MgGroupPhotoContent -GroupId <groupId> -InFile <inFile>

GroupId: OID

Permissions: owner calls (Group.ReadWrite), non-owner calls (Group.ReadWrite.All)

InFile: string path to the file to upload

Documentation

Get-UserPhoto -Identity <userId>

Get-MgUserPhoto -UserId <id>

UserId: OID/SMTP/UPN

Permissions: owner calls (User.Read), non-owner calls (User.Read.All)

Documentation

Get-UserPhoto -Identity <userId> -GroupMailbox

Get-MgGroupPhoto -GroupId <id>

GroupId: OID

Permissions: owner calls (Group.Read), non-owner calls (Group.Read.All)

Documentation

$pict = Get-UserPhoto <userId>

$pict.PictureData | Set-Content <outFileId> -Encoding byte

Get-MgUserPhotoContent -UserId <id> -OutFile <outFileId>

UserId: OID/SMTP/UPN

Permissions: owner calls (User.Read), non-owner calls (User.Read.All)

OutFile: string path to the file, which image will be saved to

Documentation

$pict = Get-UserPhoto <userId> -GroupMailbox

$pict.PictureData | Set-Content <outFileId> -Encoding byte

Get-MgGroupPhotoContent -GroupId <id> -OutFile <outFileId>

GroupId: OID

Permissions: owner calls (Group.Read), non-owner calls (Group.Read.All)

OutFile: string path to the file, which image will be saved to

Documentation

Remove-UserPhoto -Identity <userId>

Remove-MgUserPhoto -UserId <id>

UserId: OID/SMTP/UPN

Permissions: owner calls (User.ReadWrite), non-owner calls (User.ReadWrite.All)

Documentation

Remove-UserPhoto -Identity <userId> -GroupMailbox

Remove-MgGroupPhoto -GroupId <id>

GroupId: OID

Permissions: owner calls (Group.ReadWrite), non-owner calls (Group.ReadWrite.All)

Documentation

We appreciate your patience as we work towards ensuring a unified profile photo experience are here to assist you through this transition. Reach out to the team at profile-photo-pm@microsoft.com with any feedback around this change.

Microsoft 365 Profile Photo Team

Published Oct 16, 2023
Version 1.0
  • ThorstenK2's avatar
    ThorstenK2
    Brass Contributor

    We are using automation for the pictures and User.ReadWrite.All and Group.ReadWrite.All are too powerfull and unscoped for a security conscious organization to give for such a task.

    Sadly the exact WritePhoto Graph permission cant be scoped to a custom EntraID Role.

    We tried giving our app a custom role with microsoft.directory/users/basic/update but that does not work.

    Get-MgUserPhoto

    Status: 401 (Unauthorized)

    ErrorCode: UnknownError

    Please check with the EntraID guys on finding an exact delegation for this.

  • Zoddo's avatar
    Zoddo
    Copper Contributor

    Hi The_Exchange_Team 

     

    As the initial deadline for the removal of Exchange cmdlets is now very close, can you acknowledge that the blocker issues mentionned above are being handled, and will be solved before the old cmdlets gets removed?

     

    As of today the "Remove-MgUserPhoto" cmdlet which is supposed to replace Exchange's "Remove-UserPhoto" is still missing in the latest Microsoft.Graph module.

  • renehaus's avatar
    renehaus
    Copper Contributor

    The Current MS-Graph Powershell Module (2.16.0) currently has a bug with Set-MgUserPhotoContent  & Remove-MgGroupPhoto.

    This should be fixed prior to the Deprecation of the Exchange Modules. Downgrading to the last Working version of the Module (2.10.0) should not be required to keep the Scripts working.

    Here is another Thread describing the Current Problem.

     

    https://learn.microsoft.com/en-us/answers/questions/1598982/how-to-fix-weird-registry-error-when-using-powersh

  • stevesargeant's avatar
    stevesargeant
    Copper Contributor

    Zoddo

    Seems like this hasn't made it in for some reason.  Just went through this request yesterday and found that out.

    I used this command instead, inside of a PowerShell script to generate the $userid

    get-exomailbox -identity $userId | remove-userphoto

     

    Had to accept all prompts for each user, so just filled the keyboard buffer with 'Y' and walked away for a bit.

  • Zoddo's avatar
    Zoddo
    Copper Contributor

    Hello, it looks like the Remove-MgUserPhoto is missing in latest Microsoft.Graph module (v2.13.1). I can use Get-MgUserPhoto, but Remove-MgUserPhoto returns:

    Remove-MgUserPhoto is not recognized as the name of a cmdlet

    Is this something that is still not fully deployed?

  • dvs2rockin's avatar
    dvs2rockin
    Copper Contributor

    There is the issue of photo sync not working from AD to Azure and as Daniel pointed out that we use Remove-UserPhoto

    this process cannot even be automated as the ID has to be given User.ReadWrite.All permission which is not feasible 

    how is there no RBAC just for photo removal

  • DanielKlicks's avatar
    DanielKlicks
    Iron Contributor

    Our users are maintaining their user photos through an on-prem application in AD. We're syncing them from AD into Entra ID. It sometimes happens (since at least 2 years), that newly updated pictures from AD are not shown in EXO, Teams, SPO even not after days and weeks. In these cases we currently execute Remove-UserPhoto in Exchange Online to trigger the re-sync from Entra ID to EXO. Hope these kind problems are also being worked on and solved until the deprecation of the Exchange Online cmdlets?!