The script imports photos for users located in a certain Organizational Unit. To update photos on a regular basis, you need to create a scheduled task for the Domain object type that runs the script.
Note: Photos will be imported only if a user does not have a photo assigned in AD.
Parameters:
- $extensions - Specifies the extensions of the pictures to import.
- $ouDNs - Maps distinguished names (DNs) of the Organizational Units where users for which to import photos are located with the paths to shares where pictures are stored. In the paths, the {0} placeholder will be replaced with the value of the $pictureNameAttribute variable.
- $pictureNameAttribute - Specifies the LDAP name of the property whose value will be used to form file names for user pictures.
- $pictureAttribute - Specifies the LDAP name of the property where user pictures will be imported.
- $to - Specifies the address of the email notification recipient.
- $subject - Specifies the email notification subject.
- $reportHeader - Specifies the report header.
- $reportFooter - Specifies the report footer.
See Also: Import user photo.
PowerShell
$extensions = @("jpg", "png") # TODO: modify me
$ouDNs = @{
"OU=Users1,DC=domain,DC=com" = "\\server1\share\{0}.{1}"
"OU=Users2,DC=domain,DC=com" = "\\server2\share\{0}.{1}"
} # TODO: modify me
$pictureNameAttribute = "employeeID" # TODO: modify me
$pictureAttribute = "thumbnailPhoto" # TODO: modify me
# Email settings
$to = "recipient@domain.com" # TODO: modify me
$subject = "User photos updated on %datetime%" # TODO: modify me
$reportHeader = "<h3>User photo update report</h3>" # TODO: modify me
$reportFooter = "<hr /><p><i>Please do not reply to this E-mail, it has been sent to you for notification purposes only.</i></p>" # TODO: modify me
# Get the default Web Interface address
$webInterfaceAddress = "%adm-WebInterfaceUrl%"
if ([System.String]::IsNullOrEmpty($webInterfaceAddress))
{
$Context.LogMessage("Default Web Interface address not set for Adaxes service. For details, see http://www.adaxes.com/help/?HowDoI.ManageService.RegisterWebInterface.html", "Warning")
}
$updateUserNames = New-Object System.Text.StringBuilder
$notFoundFiles = New-Object System.Text.StringBuilder
# Build criteria
$criteria = New-AdmCriteria "user"
$simpleItem1 = $criteria.CreateSimple()
$simpleItem1.SetProperty($pictureAttribute).SetComparisonOperator("empty").AddValue($True)
$simpleItem2 = $criteria.CreateSimple()
$simpleItem2.SetProperty($pictureNameAttribute).SetComparisonOperator("empty").AddValue($False)
$criteria["user"].Add($simpleItem1).Add($simpleItem2)
foreach ($dn in $ouDNs.Keys)
{
# Find users
$searcher = $Context.BindToObjectByDN($dn)
$searcher.Criteria = $criteria
$searcher.SearchScope = "ADS_SCOPE_SUBTREE"
$searcher.ReferralChasing = "ADS_CHASE_REFERRALS_NEVER"
$searcher.PageSize = 500
$searcher.SetPropertiesToLoad(@($pictureNameAttribute, "objectGUID"))
try
{
$searchResultIterator = $searcher.ExecuteSearch()
$searchResults = $searchResultIterator.FetchAll()
$picturePathTemplate = $ouDNs[$dn]
foreach ($searchResult in $searchResults)
{
# Build photo path
$fileName = $searchResult.Properties[$pictureNameAttribute].Value
$picturePath = $NULL
foreach ($extension in $extensions)
{
$picturePath = [System.String]::Format($picturePathTemplate, @($fileName, $extension))
if(!(Test-Path -Path $picturePath))
{
$picturePath = $NULL
continue
}
break
}
if ($NULL -eq $picturePath)
{
$notFoundFiles.Append("<li>$fileName</li>")
continue
}
# Update user photo
$user = $Context.BindToObject($searchResult.AdsPath)
$username = $user.Get("name")
try
{
[Byte[]]$pictureBytes = [System.Io.File]::ReadAllBytes($picturePath)
$user.Put($pictureAttribute, $pictureBytes)
$user.SetInfo()
}
catch
{
$Context.LogMessage("An error occurred while updating picture for user '$username'. Error: " + $_.Exception.Message, "Warning")
continue
}
# Add user to report
$guid = [Guid]$searchResult.Properties["objectGUID"].Value
$userLink = "<a href='$webInterfaceAddress`#/Browse/$guid'>$username</a>"
$updateUserNames.Append("<li>$userLink</li>")
}
}
finally
{
$searchResultIterator.Dispose()
}
}
# Build html
$html = New-Object System.Text.StringBuilder
$html.Append($reportHeader)
$html.Append("<b>Users with updated photos</b>")
if ($updateUserNames.Length -eq 0)
{
$html.Append("<b>Users are not updated</b>")
}
else
{
$html.Append("<ol>")
$html.Append($updateUserNames.ToString())
$html.Append("</ol>")
}
$html.Append("<br/>")
if ($notFoundFiles.Length -ne 0)
{
$html.Append("<b>No picture for users with the following $pictureNameAttribute were found:</b>")
$html.Append("<ol>")
$html.Append($notFoundFiles.ToString())
$html.Append("</ol>")
}
$html.Append($reportFooter)
# Send mail
$Context.SendMail($to, $subject, $NULL, $html.ToString())
Hello Tim,
As per our check, the script works as intended. For troubleshooting purposes, could you, please, post here or send us (support[at]adaxes.com) the exact script you are using with all the modifications made?
Hello Mike,
Yes, it is possible. Should it be a single share containing pictures for users in all the OUs or each OU will have a separate share? Any additional details regarding the required script modifications will be much appreciated.
OU Company A.1 to \\server\share \company a
OU Company A.2 to \\server\share \company a
OU Company A.3 to \\server\share \company a
OU Company B to \\server\share \company b
OU Company C to \\server\share \company c
We also have jpg & png files and it would be helpful to scan and import both.
Let me know if you need any details.
Thanks!
Hello Mike,
Thank you for the provided details. We updated the script accordingly. For example, now the $ouDNs variable maps distinguished names of OUs with paths to user pictures.
One last request (I promise): Can the email include any errors from the script? Example: some users' photos are missing from the server share.
Thank you so much!
Hello Mike,
Yes, it is possible. What information do you need to be included? Would something like the below meet your needs?
No picture for users with the following employee IDs were found:
employee ID 1
employee ID 2
employee ID 3
Hello Mike,
Thank you for the confirmation. We updated the script accordingly.
"Users with updated photosUsers are not updatedNo picture for users with the following cn were found:Bob SmithBob SmithBob SmithBob SmithBob SmithBob Smith"
Can we add spaces between cn's or have them on their own line?
Hello Mike,
Sorry for the confusion, the issue occurs because the script is not properly displayed in our comment. Please, use the main script from the article, it contains all the updates you need.