I’ve created a script for uploading user pictures to the SharePoint 2010 User Profile system.
For me it worked very well. But: Use it at your own risk!
Here is the script:
#written by ingo karstein #region Check x64 host if( [System.IntPtr]::Size -ne 8) { Write-Error "Please use a x64 PowerShell host!" return } #endregion #region Load SharePoint SnapIn and DLL Remove-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint") | out-null Add-Type -AssemblyName System.DirectoryServices Add-Type -AssemblyName System.DirectoryServices.AccountManagement #Check available SharePoint Cmdlets if( (Get-Command -Noun SPWeb*) -eq $null ) { Write-Error "SharePoint SnapIn not loaded. SharePoint cmdlets missing!" return } #endregion cls #region Config Section $dom = "sharepoint.local" $dom2 = "dc=sharepoint, dc=local" $ad = @("ou=Users,dc=sharepoint,dc=local", "ou=Users2,dc=sharepoint,dc=local") $ldapFilter = "(&(objectcategory=user))" $testuser = $null #for testing purpose uncomment the following line and add the sAMAccountName of the test user #$testuser="ikarstein" #the web application url of the profile system $personalSiteHost="http://sharepoint.farm/mysitehost" #the intranet/homepage web application url $intranetSiteHost="http://sharepoint.farm" #the path to the user profile pictures. the files must be named like the sAMAccountName and with extension .jpg # example: ikarstein.jpg $imagePath="\servershareuser_pictures" #endregion $ErrorActionPreference = "Stop" #This function reads name of the folder where the pictures will be stored function GetProfilePicturesFolderName { try { $a = [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint.Portal") $name = $a.GetName() $assemblyRef = new-object System.Reflection.AssemblyName $assemblyRef.Name = "Microsoft.Office.Server.intl" $assemblyRef.Version = $name.Version $assemblyRef.SetPublicKey($name.GetPublicKey()) $assemblyRef.CultureInfo = [System.Globalization.CultureInfo]::InvariantCulture $assembly = [System.Reflection.Assembly]::Load($assemblyRef) $s_rmLocStrings = new-object System.Resources.ResourceManager ("Microsoft.Office.Server.Strings", $assembly) $s_rmLocStrings.GetString("UserProfile_UploadPicture_FolderName") } catch { $null } } #This function reads name of the SharePoint list where the pictures will be stored function GetProfilePicturesListName { try { $a = [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint.Portal") $name = $a.GetName() $assemblyRef = new-object System.Reflection.AssemblyName $assemblyRef.Name = "Microsoft.Office.Server.intl" $assemblyRef.Version = $name.Version $assemblyRef.SetPublicKey($name.GetPublicKey()) $assemblyRef.CultureInfo = [System.Globalization.CultureInfo]::InvariantCulture $assembly = [System.Reflection.Assembly]::Load($assemblyRef) $s_rmLocStrings = new-object System.Resources.ResourceManager ("Microsoft.Office.Server.Strings", $assembly) $s_rmLocStrings.GetString("MyPage_MyLists_ProfilePicture_Text") } catch { $null } } #This function returns the object for the profile picture list function GetProfilePicturesList { try { $profilePicturesListName = GetProfilePicturesListName $profileWeb.Lists | ? { $_.get_BaseTemplate() -eq 0x6d -and $_.get_Title() -ieq $profilePicturesListName } } catch { $null } } #This function removes special characters from the file name function ConvertToLegalFileName($inputName, $replacementChar) { $l = $inputName.Length; $builder = New-Object System.Text.StringBuilder($inputName) for ($i = 0; $i -lt $l; $i++) { if ([Microsoft.SharePoint.Utilities.SPUrlUtility]::IsLegalCharInUrl($inputName[$i]) -ne $true) { $builder.set_chars($i, $replacementChar) } } return $builder.ToString() } #This function returns the sub folder for pictures in the picture list function GetSubfolderForPictures { $folderName = GetProfilePicturesFolderName try { $subfolder = $profilePicturesList.get_RootFolder().Get_SubFolders().get_Item($folderName) if( $subfolder -eq $null ) { $subfolder = $profilePicturesList.get_RootFolder() } } catch { try { $subfolder = $profilePicturesList.get_RootFolder().get_SubFolders().Add($folderName) } catch { $subfolder = $null } } return $subfolder } #this function returns *multiple* objects: # 1. the MethodInfo object for "CreateThumbnail" # 2. the size of the large thumbnal picture # 3. the size of the medium thumbnail picture # 4. the size of the small thumbnail picture function InitializeUserProfilePhotosType { $a = [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.Office.Server.UserProfiles") $userPofilePhotosType = $a.GetType("Microsoft.Office.Server.UserProfiles.UserProfilePhotos") #outputs: $userPofilePhotosType.GetMethod("CreateThumbnail", [System.Reflection.BindingFlags]([System.Reflection.BindingFlags]::Static -bor [System.Reflection.BindingFlags]::NonPublic)) $userPofilePhotosType.InvokeMember("LargeThumbnailSize", [System.Reflection.BindingFlags]([System.Reflection.BindingFlags]::Public -bor [System.Reflection.BindingFlags]::Static -bor [System.Reflection.BindingFlags]::GetProperty ), $null, $null, @() ) $userPofilePhotosType.InvokeMember("MediumThumbnailSize", [System.Reflection.BindingFlags]([System.Reflection.BindingFlags]::Public -bor [System.Reflection.BindingFlags]::Static -bor [System.Reflection.BindingFlags]::GetProperty ), $null, $null, @() ) $userPofilePhotosType.InvokeMember("SmallThumbnailSize", [System.Reflection.BindingFlags]([System.Reflection.BindingFlags]::Public -bor [System.Reflection.BindingFlags]::Static -bor [System.Reflection.BindingFlags]::GetProperty ), $null, $null, @() ) } #this function returns a MethodInfo object for "EnsureTrailingSlash" method function InitializePersonalSpaceGlobalType { $a = [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.Office.Server.UserProfiles") $personalSpaceGlobalType = $a.GetType("Microsoft.Office.Server.WebControls.UserProfileHelper.PersonalSpaceGlobal") #outputs: $personalSpaceGlobalType.GetMethod("EnsureTrailingSlash", [System.Reflection.BindingFlags]([System.Reflection.BindingFlags]::Static -bor [System.Reflection.BindingFlags]::NonPublic)) } #thid function returns a MethodInfo object for "GetSmallThumbnailUrl" method function InitializeUserProfileGlobalType { $a = [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.Office.Server.UserProfiles") $userProfileGlobalType = $a.GetType("Microsoft.Office.Server.UserProfiles.UserProfileGlobal") #outputs: $userProfileGlobalType.GetMethod("GetSmallThumbnailUrl", [System.Reflection.BindingFlags]([System.Reflection.BindingFlags]::Static -bor [System.Reflection.BindingFlags]::NonPublic)) } #this function creates an absolute url for the given relative url function MakeFullUrl { param($url) return "$($temp)$($Url)" } #this function reads the users from the Active Directory function GetUsers { $ctype = [System.DirectoryServices.AccountManagement.ContextType]::Domain $context = New-Object -TypeName System.DirectoryServices.AccountManagement.PrincipalContext -ArgumentList $ctype, $dom, $dom2 $l = @() $ad | % { $domain = [ADSI]("LDAP://"+$_) $filter = $ldapFilter $ds = new-object System.DirectoryServices.DirectorySearcher($domain,$filter) $users = $ds.Findall() $users | % { $l = $l + $_ } } $identityParam = [System.DirectoryServices.AccountManagement.IdentityType]::SamAccountName $m = @() if( $testuser -ne $null ) { Write-Host "Test mode!" -ForegroundColor Red } $l | % { $san = $_.properties["samaccountname"] if( $testuser -eq $null -or $testuser -ieq $san) { $m = $m + $san[0] } } #output: $m } $profileSite = (Get-SPSite $personalSiteHost) $profileWeb = $profileSite.RootWeb $site=(Get-SPSite $intranetSiteHost) $sc = [Microsoft.Office.Server.ServerContext]::GetContext($site) $upm = New-Object "Microsoft.Office.Server.UserProfiles.UserProfileManager" -ArgumentList ($sc) $mysiteHostUrl = $upm.MySiteHostUrl $ensureTrailingSlashMethod = (InitializePersonalSpaceGlobalType) $mysiteHostUrl = $ensureTrailingSlashMethod.Invoke($null, @(, $mysiteHostUrl)) $createThumbnailMethod, $largeThumbnailSize, $mediumThumbnailSize, $smallThumbnailSize = (InitializeUserProfilePhotosType) $getSmallThumbnailUrlMethod = (InitializeUserProfileGlobalType) $profilePicturesList = GetProfilePicturesList $profilePicturesFolder = GetSubfolderForPictures $users=(GetUsers) $users | % { $currentUser = $_ Write-Host "Processing user $($currentUser)" $up=$null try { $up = $upm.GetUserProfile($currentUser) } catch { #this exception handler may be called for "renamend" users: In the AD the account name was changed but not in the SharePoint User Profil system $e=$upm.GetEnumerator() $e.reset() while( $e.movenext() ) { $u = $e.current if( $u["UserName"] -ieq $currentUser ) { $up = $u break } } } if( $up -ne $null ) { Write-Host " User found in profile store" $picture = [byte[]](Get-Content -path "$($imagePath)$($currentUser).jpg" -Encoding Byte -ErrorAction SilentlyContinue) if( $picture -ne $null ) { Write-Host " User picture found: ""$($imagePath)$($currentUser).jpg""" $dstFileName = (ConvertToLegalFileName $up["AccountName"].Value.ToString() "_") $flag = $profileWeb.get_AllowUnsafeUpdates() try { $profileWeb.set_AllowUnsafeUpdates($true) try { $stream = $bitmap = $ps = $null try { $stream = New-Object System.IO.MemoryStream @(, $picture) if( $stream -ne $null ) { $bitmap = New-Object System.Drawing.Bitmap ($stream, $true) if( $bitmap -ne $null ) { Write-Host " starting photo creation..." $p = ([System.Drawing.Bitmap]$bitmap, $largeThumbnailSize, $largeThumbnailSize, [Microsoft.SharePoint.SPFolder]$profilePicturesFolder, "$($dstFileName)_LThumb.jpg") $file = $createThumbnailMethod.Invoke($null, $p ) Write-Host " large thumnail created..." $p = ([System.Drawing.Bitmap]$bitmap, $smallThumbnailSize, $smallThumbnailSize, [Microsoft.SharePoint.SPFolder]$profilePicturesFolder, "$($dstFileName)_SThumb.jpg") $file = $createThumbnailMethod.Invoke($null, $p ) Write-Host " small thumnail created..." $p = ([System.Drawing.Bitmap]$bitmap, $mediumThumbnailSize, $mediumThumbnailSize, [Microsoft.SharePoint.SPFolder]$profilePicturesFolder, "$($dstFileName)_MThumb.jpg") $file = $createThumbnailMethod.Invoke($null, $p ) Write-Host " medium thumnail created..." $mediumUrl = $profileSite.MakeFullUrl( (MakeFullUrl $file.get_Url()) ) $smallThumbUrl = $getSmallThumbnailUrlMethod.Invoke($null, ([string]$mediumUrl)) [Microsoft.SharePoint.SPSecurity]::RunWithElevatedPrivileges( { $ps = $up.PersonalSite if( $ps -ne $null ) { $ps.get_RootWeb().set_SiteLogoUrl($smallThumbUrl) $ps.get_RootWeb().Update() } $up["PictureURL"].Value = $mediumUrl $up.Commit() } ); } } } catch { Write-Host " error occured!" Write-Error $Error[0] } finally { if( $bitmap -ne $null ) { $bitmap.dispose() } if( $stream -ne $null ) { $stream.close() $stream.dispose() } } } catch { } } finally{ $profileWeb.set_AllowUnsafeUpdates($flag) } } else { Write-Host " Users picture not found" -ForegroundColor Red } } else { Write-Host " User not found in profile store" -ForegroundColor Red } }