[Из песочницы] Загрузка фото пользователя в Active Directory с помощью PowerShell
Если вы используете Active Directory у вас используется Exchange, OwnCloud, SharePoint или другая система с возможностью отображения аватара или фото, то после прочтения данный статьи у вас появится возможность загрузить фото пользователя в AD для отображения в Outlook, Lync, на порталах SharePoint и других системах.Нашел похожую статью («Добавление фотографий в Active Directory»), но прошло много времени, решил оживить тему.Требования:
Фото сотрудников желательно в формате JPG; название файлов, желательно, стандартизировать; PowerShell и модуль Active Directory for PowerShell на компьютере; Схема Active Directory должна быть Win 2008 или новее (это не означает наличие контроллеров под Window 2008, достаточно запустит adprep с диска Windows 2008 для расширения схемы); Пользователь должен иметь права на изменение атрибутов thumbnailphoto, jpegPhoto в Active Directory (по умолчанию, пользователь может менять свою фотографию, но права можно делегировать). Минусы:
Дополнительная нагрузка на поддержку с просьбами заменить фото; Рост базы Active Directory NTDS.DIT, что может привести к проблемам репликации. Для справки:
Ограничение Active Directory на размер атрибута thumbnailPhoto и jpegPhoto 100 кб. Фото пользователя в Outlook 2010 будут отображаться даже если не установлен Exchange, достаточно иметь схему Active Directory Win 2008 или новее (Это не означает наличие контроллеров под Window 2008, достаточно запустит adprep с диска Windows 2008 для расширения схемы). Для отображения фото пользователя, в разных системах, используются разные атрибуты в Active Directory. Например для отображения в Outlook thumbnailPhoto, а для отображения в SharePoint jpegPhoto.
Автор не несет ответственности за любой возможный вред, причиненный материалами данной статьи.
В статье не приведен скрипт целиком. На вкус и цвет фломастеры разные.В действительности, моим готовым скриптом, при необдуманном использовании, проще сломать Active Directory.
Нежелающие изучать PowerShell могут воспользоваться программами:
Или допилить оснастку Active Directory User & computers
Существует несколько вариантов загрузки фото в AD с помощью PowerShell:
Используя модуль Microsoft PowerShell for Active Directory:
Import-Module ActiveDirectory
$photo = [byte[]](Get-Content C:\Photo\MyPhoto.jpg -Encoding byte)
Set-ADUser
Используя оснастку PowerShell for Exchange 2013:
Add-PSSnapin Microsoft.Exchange.Management.PowerShell.SnapIn
$photo = ([Byte[]] $(Get-Content -Path «C:\Photo\MyPhoto.jpg» -Encoding Byte -ReadCount 0))
Set-UserPhoto -Identity
Используя PowerShell и ADSI: [byte[]]$jpg = Get-Content «C:\Photo\MyPhoto.jpg» -encoding byte $user = [adsi]«LDAP://cn=user1, cn=users, dc=domain, dc=loc» $user.Properties[«jpegPhoto»].Clear () $null = $user.Properties[«jpegPhoto»].Add ($jpg) $user.Properties[«thumbnailPhoto»].Clear () $null = $user.Properties[«thumbnailPhoto»].Add ($jpg) $user.CommitChanges () Все эти примеры, подгружают фото пользователя, не изменяя размер и качество картинки.Для себя я остановился на использовании с модулем Microsoft PowerShell for Active Directory. Но при первой же попытке загрузить фото получил ошибку о невозможности подгрузить фото из файла размером 5 мегабайт. Первая идея была сконвертировать фото, сжав их до приемлемого размера. Но желание подучить PowerShell победило.
Так что усложним задачу загрузки фото. Добавим функцию изменения разрешения фото.
Функция принимает на входе полный путь к файлу, максимальное разрешение, качество сжатия.
Почти готовая функция была найдена на просторах интернета и допилена под конкретные задачи. Function resizephoto (){ Param ([Parameter (Mandatory=$True)] [ValidateNotNull ()] $imageSource, [Parameter (Mandatory=$true)][ValidateNotNull ()] $canvasSize, [Parameter (Mandatory=$true)][ValidateNotNull ()] $quality)
# функция берет файлик и ужимет его
# проверки if (!(Test-Path $imageSource)){throw («Файл не найден»)} if ($canvasSize -lt 10 -or $canvasSize -gt 1000){throw (» Параметр размер должен быть от 10 до 1000»)} if ($quality -lt 0 -or $quality -gt 100){throw (» Параметр качества должен быть от 0 до 100»)}
[void][System.Reflection.Assembly]:: LoadWithPartialName («System.Drawing»)
$imageBytes = [byte[]](Get-Content $imageSource -Encoding byte) $ms = New-Object IO.MemoryStream ($imageBytes, 0, $imageBytes.Length) $ms.Write ($imageBytes, 0, $imageBytes.Length);
$bmp = [System.Drawing.Image]:: FromStream ($ms, $true)
# разрешение картинки после конвертации $canvasWidth = $canvasSize $canvasHeight = $canvasSize
# Задание качества картинки $myEncoder = [System.Drawing.Imaging.Encoder]:: Quality $encoderParams = New-Object System.Drawing.Imaging.EncoderParameters (1) $encoderParams.Param[0] = New-Object System.Drawing.Imaging.EncoderParameter ($myEncoder, $quality) #Получаем тип картинки $myImageCodecInfo = [System.Drawing.Imaging.ImageCodecInfo]:: GetImageEncoders ()|where {$_.MimeType -eq 'image/jpeg'}
# Высчитывание кратности $ratioX = $canvasWidth / $bmp.Width; $ratioY = $canvasHeight / $bmp.Height; $ratio = $ratioY if ($ratioX -le $ratioY){ $ratio = $ratioX }
# Создание пустой картинки $newWidth = [int] ($bmp.Width*$ratio) $newHeight = [int] ($bmp.Height*$ratio) $bmpResized = New-Object System.Drawing.Bitmap ($newWidth, $newHeight) $graph = [System.Drawing.Graphics]:: FromImage ($bmpResized)
$graph.Clear ([System.Drawing.Color]:: White) $graph.DrawImage ($bmp,0,0, $newWidth, $newHeight)
# Создание пустого потока $ms = New-Object IO.MemoryStream $bmpResized.Save ($ms,$myImageCodecInfo, $($encoderParams))
# уборка $bmpResized.Dispose () $bmp.Dispose ()
return $ms.ToArray () } Вставим данную функцию в скрипт.Отрывок основной часть скрипта, прописать путь к фото, логин, табельный номер, ФИО $PhotoPath = '\\server\FOTO\' #создаем PSDrive чтобы избежать проблем с обращениям к сетевым дискам при подключённой оснастке PSSQL New-PSDrive -Name Photo -PSProvider FileSystem -Root $PhotoPath
$UserLogin = 'login' $EmployeeID = '503' $FullName = 'Full User Name' # закомментировать для уменьшения вывода write-host «Обрабатываем: `n Логин:» $UserLogin »`n номер:» $EmployeeID »`n ФИО:» $FullName # проверяем соответствие логина в AD и внешней системе $aduser = get-aduser $UserLogin -ErrorAction SilentlyContinue if ($aduser.name -ne $FullName) { # если не совпадает выводим на экран и ничего не делаем write-host «in Office » $FullName »`n in ad » $aduser.name »`nLogin » $UserLogin » `n`n» -ForegroundColor Red } else { # присваиваем EmployeeID в AD из внешней системы Set-ADUser $UserLogin -EmployeeID $EmployeeID $PhotoFile = 'Photo:\'+$EmployeeID+'.jpg' # проверяем что фото есть If (Test-Path $PhotoFile) { # Если есть фото сотрудника
# указываем путь к фото и качество $thumbnailPhoto = [byte[]]($(resizephoto $PhotoFile 64 80)) $jpegPhoto = [byte[]]($(resizephoto $PhotoFile 648 80))
# добавляем фото в thumbnailPhoto Set-ADUser $UserLogin -Replace @{thumbnailPhoto=$thumbnailPhoto} -ErrorVariable ErrorthumbnailPhoto #-WhatIf if ($ErrorthumbnailPhoto -ne $null) { # в случае ошибки write-host «Ошибка добавления thumbnailPhoto на логине »$UserLogin » ID » $_.autokey exit } # добавляем фото в jpegPhoto Set-ADUser $UserLogin -Replace @{jpegPhoto=($jpegPhoto)} -ErrorVariable ErrorjpegPhoto #-WhatIf if ($ErrorjpegPhoto -ne $null) { # в случае ошибки write-host «Ошибка добавления jpegPhoto на логине »$UserLogin » ID » $_.autokey exit } if (!$ErrorthumbnailPhoto -and!$ErrorjpegPhoto) { # Если без ошибок # закомментировать для уменьшения вывода write-host 'Обработали…' -ForegroundColor Green }
} else { # Если нет фото Write-Host » Фото » $PhotoFile » для » $UserLogin » не найдено» -foregroundcolor red }
} Путь к фото задан через PSDrive, так как после подключения модуля PowerShell PSSQL для работы с MS SQL текущий путь меняется на PS SQLSERVER:\> и обращение к сетевым ресурсам, без смены папки, становится невозможным. Фото хранится на сетевом ресурсе, где имя файл табельный номер. В примере убрано логирование и обработка ошибок.
Выгрузка фото из Active Directory: Несколько примеров для проверки корректности загрузки фото в Active Directory.
Используя модуль Microsoft PowerShell for Active Directory:
Import-Module ActiveDirectory
$user = Get-ADUser
Или написать свой телефонный справочник как titulusdesiderio» «Telephone Directory» с блэкджеком и фото.