
Objective
I have recently tasked to download photos from Office 365 and those will be used to upload in different system. I could see many ways to download photos but I have put together a script by taking help from many other scripts and finally putting a single one.
Reason
This script will help to specify multiple OUs of Active Directory and it has error handling of not finding anyone who don’t have mail address.
Script
#Remove Old Pictures before downloading new ones, We are using PathType to delete only files $LogLocation="C:\Scripts\UserPhoto\Photos" if(Test-Path $LogLocation\* -PathType leaf) { Remove-Item $LogLocation\* -Recurse } # This function will download the pictures in defined resolutions from Office 365 using EWS Protocol, This method is much faster then running Get-UserPhoto function Get-Office365Photo($EmailAddress,$Credential) { $wc = New-Object System.Net.WebClient $wc.credentials = $Credential # Build the URL that'll return the jpeg of the user's photo in HR48x48, HR64x64, HR96X96, HR120X120, HR240X240, HR360X360, HR432X432, HR504X504, HR648X648 $url = "https://outlook.office365.com/ews/exchange.asmx/s/GetUserPhoto?email=$EmailAddress&size=HR648x648" # Build a path to export it to (.\sourabh.jha@alwayslearn.xyz.jpg) $outPath = "C:\Scripts\UserPhoto\Photos\$EmailAddress.jpg" try { # Download the image and save it to the current directory, We are using DownloadFileAsync instead of DownloadFile because DownloadFile will stop if it sees photo not found error. DownloadFileAsync will make files for all users with 0 kb and gradually it will download all of them. $wc.DownloadFileAsync($url,$outPath) return $outPath } catch { throw $_ } } # Get the credential to allow image download, speficy a global administrator credential $AdminUsername = " " $AdminPassword = " " $SecurePassword = ConvertTo-SecureString $AdminPassword -AsPlainText -Force $Cred = New-Object -TypeName System.Management.Automation.PSCredential -argumentlist $AdminUsername,$SecurePassword # Get every AD user with valid mail attrbute of two OUs, You can type more OUs comma delimited. $searchBases = "OU=AllINDIA,DC=alwayslearn,DC=net", "OU=AllUS,DC=alwayslearn,DC=net" $users = @() foreach ($searchBase in $searchBases) { $users += Get-ADuser -filter * -SearchBase $searchBase -Properties mail | where-object {$_.mail -ne $null} | select mail } $users| Export-Csv -Path C:\Scripts\UserPhoto\Users.csv -NTI -Append # Now it will use input file for primary email address import-csv C:\Scripts\UserPhoto\Users.csv | %{Get-Office365Photo -EmailAddress $_.mail -Credential $Cred} # Delete the input file Remove-Item C:\Scripts\UserPhoto\Users.csv