I have been asked this often – “Our company takes employee photos and we store it on a network folder. We would like to use the company photos instead of users uploading their own photos?”
Background:
The way SharePoint user profiles image work is –
- All the images are stored on http://<MySiteURL>/User%20Photos/Forms
- For each user profile there are three sizes for the images. When you upload an image SharePoint converts those to three different sizes and stores it in the above image library.
After googling I found lot of code that would upload the images to the above mentioned library but there was lot of code that would also convert the images into the different sizes and store it. Initially I was inclined towards trying the above route but soon I realized that the client for whom I was working was storing the images with employeeID.jpg format. Most of the code I found online was talking about network name. So, I would have to first compare the employee ID get the image convert it to SharePoint understandable size and then upload it to the library. I had to get this done in 2 hours. So, I started looking for how can I just point the pictureURL property for the User Profile to point to the network drive and just be done with it.
So, there were two options –
- Write C# code to populate the pictureURL property. But this would mean I would have to create a setup application and then install it on the server. Didn’t like the option…
- Somehow work with PowerShell Script. Did more googling and found the various pieces of the puzzle and brought it together. Following is the solution whch works great for our client.
Solution:
The solution assumes you have already created the User Profile connection with AD. If you are using the EmployeeID as your identifier for your user profile images then make sure you create User Profile property for employeeID and map it to the AD employeeID field. You also need to setup the MySites web application and the url stuff.
Once your user profile is setup and the import is performed. You have to make sure that you have given full control of User Profile Service Application to the user that would be running the PowerShell Script. In order to do that follow these steps –
- Go to Central Administration.
- Click on Application Management.
- Click on Manage Service Applications.
- Select the User PRofile Service Application. Do not click on the Service Application link.
- Click on Permissions on the Service Applications Ribbon.
- If the user you are using to run the PowerShell Script is not in this list then add it and give it full control.
Once the above steps are done now you can use the following PowerShell Script to point the PictureURL to the appropriate location –
#Get the My Site URL Replace the <MySites URL with your url
$siteUrl = “”
#Get the Site Context
$site = Get-SPSite $siteUrl
$servcontext = Get-SPServiceContext $site
#Initiate the Profile Manager and get the user profiles
$profileManager = New-Object Microsoft.Office.Server.UserProfiles.UserProfileManager($servcontext)
$profiles = $profileManager.GetEnumerator()
#The property names for picture url and employeeid.
$pictureURLAttribute = “PictureURL”
$employeeIDAttribute = “EmployeeId”
# Loop through all user profiles.
foreach ($uProfile in $profiles)
{
# Make sure there is some value in the employee ID property
if ($uProfile[$employeeIDAttribute] -ne ”)
{
#Get the EmployeeID for the employee.
$EmployeeID = $uProfile[$employeeIDAttribute].toString()
#Format the Picture url. Since this example is for network folders the format starts with \\ Replace the
$netPictureURL = “\\<network folder>\$EmployeeID.jpg”
#Change the Picture URL information and then commit the record.
$uProfile[$pictureURLAttribute].Value = $netPictureURL
$uProfile.Commit()
}
}
Run the above PowerShell script and all your user profiles will point to the network drive for employee photo.
But if you try to search the results you will still not see the photos on the Search results. Even after running the incremental crawl does not help on the Search Results. Here is the reason why it does not work. If you look at the Search results XSLT code, it actually blocks files that start with \\ or file: or //. You need to modify the XSLT to allow the image files that start with \\ or file:. In order to do that follow these steps –
- Go to peopleresults.aspx page and edit it.
- Edit the People core search results web part.
- Expand Display properties.
- Uncheck the Use Location Visualization checkbox.
- Click on XSL Editor button.
- Search for GetPicUrl. The code should be as follows –
<xsl:template name=”GetPicUrl”>
<xsl:param name=”PicUrl”/>
<xsl:param name=”PlaceHolderUrl”/>
<xsl:choose>
<xsl:when test=”string-length($PicUrl) < 1 or starts-with($PicUrl, ‘file:’) or starts-with($PicUrl, ‘\\’) or starts-with($PicUrl, ‘//’)”>
<xsl:value-of select=”$PlaceHolderUrl”/>
xsl:when>
<xsl:otherwise>
<xsl:value-of select=”$PicUrl”/>
xsl:otherwise>
xsl:choose>
xsl:template>
- Note that the PicUrl is being checked for blank or if it starts with file: or \\ or //. If any of these conditions are true then it displays the default picture if it is false then it actually displays the pictureURL. . Remove all the starts-with code and now the images are visible in the search results page. Your code should now look like –
<xsl:template name=”GetPicUrl”>
<xsl:param name=”PicUrl”/>
<xsl:param name=”PlaceHolderUrl”/>
<xsl:choose>
<xsl:when test=”string-length($PicUrl) < 1″>
<xsl:value-of select=”$PlaceHolderUrl”/>
xsl:when>
<xsl:otherwise>
<xsl:value-of select=”$PicUrl”/>
xsl:otherwise>
xsl:choose>
xsl:template>
- Just in case anyone is wondering how does this template get call. Search for pictureURL. You will get the code which calls this template and passes the pictureURL managed property as parameter.
The above step should assist you with your company policies of using the company photos for user profiles and not the employee uploaded photos.
Happy SharePoint Searching. Use the above code at your own risk 🙂
CAT Exam Results
December 11, 2015 at 12:21 am
Greetings I am so excited I found your blog page, I really found you by error,
while I was researching on Yahoo for something else, Anyways I am here now and would just like to say many thanks for a marvelous
post and a all round interesting blog (I also love the theme/design), I don’t
have time to look over it all at the moment but I have book-marked it and also added in your
RSS feeds, so when I have time I will be back to read more, Please do
keep up the superb job.