Table of Contents
Use Graph SDK Cmdlets to Manage User and Group Photos
According to message center notification MC678855 (2 October), effective November 30, 2023, Microsoft will retire the Exchange Online management cmdlets to manipulate photos for mailboxes (Get-, Set-, and Remove-UserPhoto). This is part of the work to improve the way Microsoft 365 manages and displays user photos and moves the photo storage location away from Exchange Online to Entra ID. Microsoft says that this will create “a coherent user profile image experience by retiring legacy profile photo services.”
Basically, this effort resolves the inconsistencies that crept into user photo handling through Exchange and SharePoint doing their own thing, largely because of their on-premises roots. Delve attempted to fix the problem in 2015 but never really went anywhere. After that, Microsoft started to use Exchange Online to host photos and synchronize from there, but it’s a better idea to use Entra ID and have all workloads come to a common place for photo data.
Replacement User Photo Cmdlets
The replacement cmdlets for user photo management are in the Microsoft Graph PowerShell SDK:
- Set-MgUserPhotoContent: Add a photo to an Entra ID account. You can add JPEG or PNG files of up to 4 MB. Entra ID can store photos with a large pixel count. I have commonly uploaded photos sized at 8256 x 5504 pixels. When applications fetch photos to use, they can specify what sized photo they wish Entra ID to provide ranging from a thumbnail (48 x 48 pixels) to a high-definition photo as used in Teams meetings.
- Get-MgUserPhoto: Check if an account has photo data in the profilePhoto property.
- Update-MgUserPhoto: According to the documentation, this cmdlet “updates the navigation photo in users.” That doesn’t make much sense, so I asked the SDK development group to ask what the text really means. As it turns out, this cmdlet is a duplicate of Set-MgUserPhotoContent, so you can ignore it.
- Remove-MgUserPhoto: Remove user photo information from an account.
Set-MgUserPhotoContent -Userid Jim.Smith@office365itpros.com -Infile "c:\temp\Jim.Smith.jpg"
From an administrator perspective, the impact of the change is a need to review scripts that call the old cmdlets to replace them with the SDK cmdlets. The changes to the script are likely to involve:
- Call the Connect-MgGraph cmdlet to connect to the SDK.
- Find target user accounts instead of mailboxes.
- Remove the references to Get-UserPhoto and Set-UserPhoto.
- Use the Get-MgUserPhoto cmdlet to find if a target mailbox has a photo and the Set-MgUserPhotoContent cmdlet to update the photo if necessary (and a suitable file is available).
To provide a working example, I updated the script mentioned in this article. You can download the full script from GitHub. Remember that Graph permissions work differently to the permissions granted when an account holds the Exchange administrator or Global administrator roles for a tenant. Using the SDK in an interactive session to update photos will only work if the signed in account holds one of the two roles mentioned above and consent is granted for the SDK app to use the Directory.ReadWrite.All permission.
Because it’s a mailbox cmdlet and supports the GroupMailbox switch, the Set-UserPhoto cmdlet can set photos for Microsoft 365 groups. The Set-MgUserPhotoContent cmdlet only handles user accounts. To update the photos for Microsoft 365 groups, it’s necessary to use the Set-MgGroupPhotoContent cmdlet. Alternatively, for team-enabled groups, you can use the Set-TeamPicture cmdlet from the Microsoft Teams module.
I wrote an article describing how to update photos for Microsoft 365 groups. Updating the associated script wasn’t quite as simple because the Get-MgGroupPhoto cmdlet doesn’t return a thumbnail identifier. The foundation of the original script is that the thumbnail identifier could tell the script if the group already had a photo. This is now not possible, so the updated script (available from GitHub) is a rewritten and simplified version of the original.
Another Example of Change
This transition is yet another example of recent change in the Microsoft 365 PowerShell space. Exchange Online has just turned off Remote PowerShell and we’re on the final stretch of deprecation for the Microsoft Online Services module (the cmdlets that deal with license assignment have already stopped working). Keeping up to date with cmdlet changes can take some time but it’s an essential task.
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.