SharePoint Server 2016 で AD にプロファイル画像をエクスポートする方法

(こちらの記事は「How to export profile picture to Active directory in SharePoint 2016」の日本語訳となります。)

SharePoint Server 2016 の標準機能では従来のバージョンでサポートされていた AD へのプロファイル画像のエクスポートがサポートされなくなりました。
SharePoint Server 2016 において引き続き AD へのプロファイル画像のエクスポート機能を利用されたい場合は独自のソリューションを開発していただく必要があります。
SharePoint 管理シェルで実行できる以下のサンプルコードでは、SharePoint のユーザープロファイルにアップロードされたプロファイル画像を簡易的に AD にエクスポートできます。

!!!重要!!!
本サンプルコードは現状有姿のままで提供されるものであり、マイクロソフトにてその動作を保証するものではありません。運用環境でのご利用にあたってはお客様の責任において十分にテストしていただきますようお願いいたします。また、AD 属性を直接変更するものとなりますので、大規模な環境で実施される場合は、適切なエラー処理や分割更新などの追加の処理を実装していただくことを推奨いたします。

 #Sample provided As-Is - Use after sufficient testing. 
#replace these details - User name, domain, My site host.
$mySiteUrl = "https://sps2016/my"
$context = Get-SPServiceContext (Get-SPSite $mySiteUrl)
$profileManager = New-Object Microsoft.Office.Server.UserProfiles.UserProfileManager($context)
$allprofiles = $profileManager.GetEnumerator()

foreach($profile in $allprofiles){
  $pictureUrl = $profile["PictureUrl"].Value
  if ($pictureUrl -ne $null){
    $pictureUrl = ($pictureUrl).Replace("MThumb","LThumb")
    $library = (Get-SPWeb $mySiteUrl).GetList($pictureUrl.Remove($pictureUrl.LastIndexOf("/") + 1))
    $file = $library.Folders[0].Folder.Files[$pictureUrl.Substring($pictureUrl.LastIndexOf("/") + 1)]
    $binary = $file.OpenBinary()

    #Put the picture image to the AD
    $username = $profile.AccountName.Substring($profile.AccountName.LastIndexOf("\") + 1)
    $domainname = $profile.AccountName.Remove($profile.AccountName.LastIndexOf("\"))
    $addomain = [System.DirectoryServices.ActiveDirectory.Domain]::GetDomain((New-Object System.DirectoryServices.ActiveDirectory.DirectoryContext('Domain', $domainname)))
    $root = $addomain.GetDirectoryEntry()
    $search = [System.DirectoryServices.DirectorySearcher]$root
    $search.Filter = "(&(objectclass=user)(objectcategory=person)(samAccountName=$username))"
    $result = $search.FindOne()
    if ($result -ne $null){
      $user = $result.GetDirectoryEntry()
      $user.put("thumbnailPhoto", $binary)
      $user.setinfo()
      Write-Host $profile.AccountName "updated"
    }
    else {Write-Host $profile.AccountName "does not exist in domain " $domainname}
  }
  else {Write-Host $profile.AccountName "does not have profile picture"}
}

特定のユーザーで AD の thumbnailPhoto にアップロードされた画像を取得して正常にアップロードされているか確認するには以下のサンプルコードを使用します。

 $aduser = [ADSI] "LDAP://cn=user01,cn=Users,dc=contoso,dc=com"
$data = $aduser.Properties["thumbnailPhoto"]
[IO.File]::WriteAllBytes("C:\out.jpg",$data.Value)

特定のユーザーで AD の thumbnailPhoto にアップロードされた画像を消去するには以下のサンプルコードを使用します。

 $aduser = [ADSI] "LDAP://cn=user01,cn=Users,dc=contoso,dc=com"
$aduser.Properties["thumbnailPhoto"].Clear()
$aduser.CommitChanges()