skip to Main Content

I have a script that checks if a user has a photo in 365, and if not, checks to see if we have a photo for the user on file. If we do have a photo it will upload using Set-UserPhoto (I do not have access to Set-MgUserPhotoContent in our environment).

Issue being, after uploading about 5-6 photos, I get a "ConvertTo-Json : Exception of type ‘System.OutOfMemoryException’ was thrown" error. Looking for suggestions and code examples of how I would prevent this so I can generate a report a the end of the script.

foreach ($Object in $PictureStatus) {
    $Name = $Object.DisplayName
    $Picture= Get-MgUserPhoto -UserID $Object.UserPrincipalName -erroraction 'silentlycontinue'
    Write-Progress -Activity 'Processing' -CurrentOperation $name -PercentComplete (($counter / $picturestatus.count) * 100)
    Start-Sleep -Milliseconds 200

        if ($Picture -ne $Null){
              
                        #has a picture in O365.
                        $Properties = [ordered]@{'UserName'=$Name;'Picture Present'='True';'Picture on File'='NA';'Picture Uploaded'='False'}

                        $Output_365Report += New-Object -TypeName PSObject -Property $Properties


                     }Else {

                        $TempVari=Get-ChildItem -Filter "$Name*" -File -Path $PhotoDatabase | where Length -gt 14kb
                        #Write-Output $TempVari                      

                              if ($TempVari -eq $null){
            
                                    #no Picture in Database
                                    $Properties = [ordered]@{'UserName'=$Name;'Picture Present'='False';'Picture on File'='False';'Picture Uploaded'='False'}

                                    $Output_365Report += New-Object -TypeName PSObject -Property $Properties

                              } else{
            
                                    #Photo Upload to 365
                                    Set-UserPhoto -Identity $Object.SamAccountName -PictureData ([System.IO.File]::ReadAllBytes("$PhotoDatabase"+"$TempVari")) -Confirm:$False
                                    
                                    $Properties = [ordered]@{'UserName'=$Name;'Picture Present'='False';'Picture on File'='True';'Picture Uploaded'='True'}

                                    $Output_365Report += New-Object -TypeName PSObject -Property $Properties
                                }
                                
}

I have experimented with using [System.IO.MemoryStream]::new() instead of ReadAllBytes, but havent been able to get the code to work with Set-UserPhoto. I am not an expert on Powershell (for now)..

2

Answers


  1. Chosen as BEST ANSWER

    I found that the Out of memory error was being caused by the Size of the photo being uploaded.. If the image was above roughly 3 MB it could kick out an error. If I added -erroraction "continue" to the command the script keeps running fine, uploading anything of an appropriate size.

    If anyone has a suggestion on how to upload the photos larger I am all ears, however for now the script is mostly working (Script is logging the errors and generates a report). For now, worst case scenario is we manually resize the photos above 3 MB and upload them again.


  2. I hope this can fix your problem

    $Output_365Report = @()
    
    foreach ($Object in $PictureStatus) {
        $Name = $Object.DisplayName
        $Picture = Get-MgUserPhoto -UserID $Object.UserPrincipalName -ErrorAction 'SilentlyContinue'
        Write-Progress -Activity 'Processing' -CurrentOperation $Name -PercentComplete (($counter / $PictureStatus.Count) * 100)
        Start-Sleep -Milliseconds 200
    
        if ($Picture -ne $Null) {
            # Has a picture in O365.
            $Properties = [ordered]@{
                'UserName' = $Name
                'Picture Present' = 'True'
                'Picture on File' = 'NA'
                'Picture Uploaded' = 'False'
            }
        } else {
            $TempVari = Get-ChildItem -Filter "$Name*" -File -Path $PhotoDatabase | Where-Object Length -gt 14kb
    
            if ($TempVari -eq $null) {
                # No Picture in Database
                $Properties = [ordered]@{
                    'UserName' = $Name
                    'Picture Present' = 'False'
                    'Picture on File' = 'False'
                    'Picture Uploaded' = 'False'
                }
            } else {
                # Photo Upload to 365
                foreach ($File in $TempVari) {
                    Set-UserPhoto -Identity $Object.SamAccountName -PictureData ([System.IO.File]::ReadAllBytes("$PhotoDatabase$($File.Name)")) -Confirm:$False
    
                    $Properties = [ordered]@{
                        'UserName' = $Name
                        'Picture Present' = 'False'
                        'Picture on File' = 'True'
                        'Picture Uploaded' = 'True'
                    }
                    break # Assuming you only want to upload one picture per user
                }
            }
        }
    
        $Output_365Report += New-Object -TypeName PSObject -Property $Properties
    }
    
    $Output_365Report | ConvertTo-Json -Depth 99
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search