Get-UserPhoto Error: There is no photo stored here

On August 23, 2023, Exchange Online PowerShell started throwing an error when retrieving user photos.

Specifically, the issue is seen when running the following EXO PowerShell command:

PS C:\> Get-UserPhoto -Identity lene.hau

The command will hang for around one minute before the following “garbage” error message is produced:

Write-ErrorMessage : |Microsoft.Exchange.Configuration.CmdletProxyException|Error on proxy command
  'Get-UserPhoto -Identity:'CN=Lene Hau,OU=e365m.onmicrosoft.com,OU=Microsoft Exchange Hosted
  Organizations,DC=EURPR09A010,DC=PROD,DC=OUTLOOK,DC=COM'' to server PR2PR09MB3001.eurprd09.prod.
  outlook.com: Server version 15.20.6699.0000, Proxy method PSWS:
InternalServerError: Error executing cmdlet : {
  "code": "InternalServerError",
  "message": "Error executing cmdlet",
  "details": [
    {
      "code": "Client",
      "target": "EURPR09A010.PROD.OUTLOOK.COM/Microsoft Exchange Hosted Organizations/e365m.
                 onmicrosoft.com/Lene Hau",
      "message": "|Microsoft.Exchange.Data.Storage.UserPhotoNotFoundException|There is no photo
                  stored here."
    }
  ],
  "innererror": {
    "message": "Error executing cmdlet",
    "type": "Microsoft.Exchange.Admin.OData.Core.ODataServiceException",
    "stacktrace": "   at Microsoft.Exchange.AdminApi.CommandInvocation.CommandInvocation.
    InvokeCommand(QueryContext queryContext, CmdletInvokeInputType cmdletInvokeInputType)\r\n at
    Microsoft.Exchange.Admin.OData.Core.PathSegmentToExpressionTranslator.Translate(
    OperationImportSegment segment)\r\n at Microsoft.Exchange.Admin.OData.Core.QueryContext.
    ResolveQuery(ODataContext context, Int32 level)\r\n at Microsoft.Exchange.Admin.OData.Core.
    Handlers.OperationHandler.Process(IODataRequestMessage requestMessage, IODataResponseMessage
    responseMessage)\r\n at Microsoft.Exchange.Admin.OData.Core.Handlers.RequestHandler.Process
    (Stream requestStream)",
    "internalexception": {
      "message": "Exception of type 'Microsoft.Exchange.Management.PSDirectInvoke.
                  DirectInvokeCmdletExecutionException' was thrown.",
      "type": "Microsoft.Exchange.Management.PSDirectInvoke.DirectInvokeCmdletExecutionException",
      "stacktrace": "   at Microsoft.Exchange.Management.PSDirectInvoke.PSDirectInvokeCmdletFactory.
       InvokeCmdletInternal[TCmdlet,TResult](Func`1 createCmdlet, Action`1 setParameterDelegate,
       List`1 captureAdditionalIO, List`1 directInvokeExceptions, Boolean
       shouldAllowProactiveProxyToReturnRoutingHint)"
    }
  },
  "adminapi.warnings@odata.type": "#Collection(String)",
  "@adminapi.warnings": []
}.
At C:\Users\Skrubbeltrang\AppData\Local\Temp\tmpEXO_z2hcndsv.xxg\tmpEXO_z2hcndsv.xxg.psm1:1178
  char:13 Write-ErrorMessage $ErrorObject
          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [Get-UserPhoto], CmdletProxyException
    + FullyQualifiedErrorId : [Server=AM7PR09MB3877,RequestId=ffda7356-3e07-f3f9-dae6-6529b7069d2f,
    TimeStamp=Wed, 23 Aug 2023 13:49:51 GMT],Write-ErrorMessage

When we initially logged the issue, no errors were listed in the Exchange Online health status.

Additionally, this is not the first time we have observed strange behavior in relation to Exchange Online user photos.

In early 2022, retrieving an empty (null) user photo using the Get-UserPhoto command changed from delivering an immediate error message to a one-minute hang followed by an error message.

Microsoft never offered any public explanation of this behavior change, and we created a workaround in our scripting to check the mailbox “HasPicture” attribute before retrieving the user photo.

It’s very concerning that unannounced changes are made to the Exchange Online infrastructure, wrongly assuming that “nothing will change for customers” and “nobody will notice.”

We are closely monitoring if this problem will be solved or recorded as another poorly planned change to Exchange Online.

*** UPDATE I 2023-08-25***

We didn’t receive any feedback from Microsoft on this (ticket created via Partner Support) in two days.

Having little faith in the quality of support we did some research and found that the same functionality is available from the MS Graph PowerShell API:

Get-MgUserPhotoContent -UserId lene.hau@azure.skrubbeltrang.com -OutFile c:\tmp\LeneHau.jpg

Final words: It’s incredibly disappointing and concerning that part of the EXO PowerShell API stops working from one minute to the other without any communication from Microsoft (before or after).

It makes life very hard for application developers and busy sys-admins who rely on scripting and often are stretched to the limit.

*** Update II 2023-09-01 ***

And now we just received feedback from a client that Get-UserPhoto is working again, and we can verify that in our own tenant.

A global outage of Get-UserPhoto happened for about a week.

Zero information from Microsoft about what happened, and the issue never came up in the Exchange Online health monitor… Hmmm…

*** Update III 2023-10-03 ***

Finally, after waiting for about a month, Microsoft responded to the incident we logged on this issue.

This is the feedback we received:

Retirement of Get-UserPhoto, Set-UserPhoto

The general advice, “consider updating training and documentation as appropriate,” seems not to care much about scripts and third-party applications.

It’s strange and quite concerning that the retirement of EXO CmdLets pops up three months before the scheduled retirement date, and, apparently, still no public information is available.