Active Directory – Extracting user photo’s

You may or may not know this, but Active Directory stores profile images for use in Outlook and to feed into other applications such as Skype for Business. The image in question is the one visible when you open up your contact card:

Outlook Contact Card

Why would to want to extract the image I hear you ask? Because there is no way of viewing the image without extracting it. This is due to the storage method that Active Directory uses.

Param(
    [parameter(Mandatory=$true)][alias("User")]$Username,
    [parameter(Mandatory=$true)][alias("Location")]$PicLocation,
    [parameter(Mandatory=$true)][alias("Picture Name")]$PicName
    )

#Import-Module ActiveDirectory
$user = Get-ADUser $Username -Properties thumbnailPhoto
$path = Join-Path -Path $PicLocation -ChildPath $PicName
$user.thumbnailPhoto | Set-Content $path -Encoding byte

As always, let’s break the code down into it’s constituent parts. Our code will require the input of three pieces of information to export the image, the user whose image we require, where it is to be saved and what it is to be called. The Param section sets up the requirement for user input using the Mandatory command.

Param(
    [parameter(Mandatory=$true)][alias("User")]$Username,
    [parameter(Mandatory=$true)][alias("Location")]$PicLocation,
    [parameter(Mandatory=$true)][alias("Picture Name")]$PicName
    )

At the risk of constantly repeating myself, the Import-Module command brings in the Active Directory cmdlets and requires that RSAT(Remote Server Administration Tools) is installed.

Import-Module ActiveDirectory

Next, we go off and get the actual value of the picture data that resides in Active Directory:

$user = Get-ADUser $Username -Properties thumbnailPhoto

Now we need to do at least a bit of error checking. As their is a risk that a backslash may or may not be entered, we use the Join-Path cmdlet to take care of it:

$path = Join-Path -Path $PicLocation -ChildPath $PicName

Finally, we save the data out as an image file:

$user.thumbnailPhoto | Set-Content $path -Encoding byte

We could have also got around the file path issue by make the file name and location a single string, but a message detailing requirements of the file path would only be achieved by setting the Picture parameter Mandatory command to $false and adding a Read-Host request.