Используем фото Active Directory для профиля пользователя Windows

Используем фото Active Directory для профиля пользователя Windows

Большинство приложений Microsoft (Outlook, SharePoint, Office365, Skype for Business) используют фотографию текущего залогиненого пользователя из Active Directory (Azure AD) в качестве аватары пользователя в своем интерфейсе. В этой статье мы покажем, как использовать фото пользователя из Active Directory в качестве изображения (аватары) для профиля пользователя Windows, который отображается на экране приветствия, экране блокировки, в стартовом меню и т.д.

Для решения этой задачи мы будем использовать небольшой PowerShell логон-скрипт. Скрипт должен запускаться при входе пользователя в Windows, получать фото пользователя из Active Directory (атрибут thumbnailPhoto) и задавать его в качестве аватарки профиля пользователя Windows.

фото пользователя в windows из active directory

 

Фото пользователя в Active Directory

Фото пользователя можно хранить в специальном атрибуте (
thumbnailPhoto
) учетной записи в Active Directory. Вы можете задать фотографии своим пользователей с помощью сторонних программ, или с помощью командлета Set-ADUser из модуля ActiveDirectory для Windows PowerShell

  1. Сохраните фото пользователя на диск в формате JPEG/BMP (размер файла с фотографией должен быть не более 100 Кб и разрешением до 96×96 пикселей);
  2. Чтобы загрузить фото учетной записи divanov, выполните команды:
    $photo = [byte[]](Get-Content C:PSdivanov_photo.jpg -Encoding byte)
    Set-ADUser divanov -Replace @{thumbnailPhoto=$photo}
  3. Откройте консоль ADUC, перейдите на вкладку редактора атрибутов и убедиться, что атрибут thumbnailPhoto теперь содержится значение. атрибут пользователя thumbnailPhoto в active directory

Настройка групповой политики для загрузки аватары пользователя в Windows

Теперь нужно настроить групповую политику, которая будет запускать PowerShell скрипт при входе пользователя.

  1. Откройте консоль управления доменными групповыми политиками Group Policy Management Console (GPMC.msc). Создайте новую GPO и назначьте ее на OU (Organizational Unit) с пользователями;
  2. В Windows информация об аватаре пользователя (путь к JPG картинке, использующейся для профиля пользователя) хранится в системной ветке реестра HKLMSOFTWAREMicrosoftWindowsCurrentVersionAccountPictureUsers. Вам нужно разрешить пользователям менять фото профиля. Для этого нужно изменить права на эту ветку реестра через GPO;
  3. Перейдите в раздел Computer Configuration -> Policies -> Windows Settings -> Security Settings -> Registry. Создайте новый ключ реестра (Add key) с путем MACHINESOFTWAREMicrosoftWindowsCurrentVersionAccountPictureUsers;Ветка реестра AccountPicture Users
  4. В открывшемся окне с настройкой разрешений (Database Security) нужно предоставить право Full Control для всех пользователей домена (группа [DomainName]Users);
  5. В следующем диалоговом окне выберите Replace Existing permission on all sub keys with inheritable permissions (иначе у пользователей не будет прав на вложенные ветки реестра);Права на ветку для доменных пользователей
  6. Включите режим обработки замыкания GPO (Computer Configuration -> Administrative Templates -> System -> Group Policy -> Configure user Group Policy Loopback Processing mode = Merge). В этом режиме можно применять политику к OU с пользователями. gpo- включите режим обработки замыкания GPO

Задать фото пользователя Windows с помощью PowerShell

Далее нужно создать PowerShell скрипт, который будет получить фото текущего пользователя из Active Directory, сохранять его в JPG файл и установить его в качестве иконки профиля пользователя.

Есть два варианта получения фото из AD: с помощью командлета Get-ADUser из модуля ActiveDirectory (этот модуль должен быть установлен на всех компьютерах через RSAT, или достаточно скопировать необходимые файлы модуля RSAT-AD-PowerShell без установки RSAT). Чтобы скрипт был универсальным и корректно работал в том числе на Windows 7, мы не будем использовать модуль RSAT-AD-PowerShell, а обратимся к AD через класс ADSISearcher.

Код скрипта SetADPicture.ps1:


Function ResizeImage {
Param (
[Parameter(Mandatory = $True, HelpMessage = "image in byte")]
[ValidateNotNull()]
$imageSource,
[Parameter(Mandatory = $true, HelpMessage = "Параметр размер должен быть от 16 до 1000")]
[ValidateRange(16, 1000)]
$canvasSize,
[Parameter(Mandatory = $true, HelpMessage = "Параметр качества должен быть от 1 до 100")]
[ValidateRange(1, 100)]
$ImgQuality = 100
)
[void][System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")
$imageBytes = [byte[]]$imageSource
$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, $ImgQuality)
#Получаем тип картинки
$myImageCodecInfo = [System.Drawing.Imaging.ImageCodecInfo]::GetImageEncoders() | Where-Object { $_.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()
}
$ADUserInfo = ([ADSISearcher]"(&(objectCategory=User)(SAMAccountName=$env:username))").FindOne().Properties
$ADUserInfo_sid = [System.Security.Principal.WindowsIdentity]::GetCurrent().User.Value
If ($ADUserInfo.thumbnailphoto) {
$img_sizes = @(32, 40, 48, 96, 192, 200, 240, 448)
$img_base = "C:UsersPublicAccountPictures"
$reg_key = "HKLM:SOFTWAREMicrosoftWindowsCurrentVersionAccountPictureUsers$ADUserInfo_sid"
If ((Test-Path -Path $reg_key) -eq $false) { New-Item -Path $reg_key } { write-verbose "Reg key exist [$reg_key]" }
Try {
ForEach ($size in $img_sizes) {
$dir = $img_base + "" + $ADUserInfo_sid
If ((Test-Path -Path $dir) -eq $false) { $(New-Item -ItemType directory -Path $dir).Attributes = "Hidden" }
$file_name = "Image$($size).jpg"
$path = $dir + "" + $file_name
Write-Verbose " Crete file: [$file_name]"
try {
ResizeImage -imageSource $($ADUserInfo.thumbnailphoto) -canvasSize $size -ImgQuality 100 | Set-Content -Path $path -Encoding Byte -Force -ErrorAction Stop
Write-Verbose " File saved: [$file_name]"
}
catch {
If (Test-Path -Path $path) {
Write-Warning "File exist [$path]"
}
else {
Write-Warning "File not exist [$path]"
}
}
$name = "Image$size"
try {
$null = New-ItemProperty -Path $reg_key -Name $name -Value $path -Force -ErrorAction Stop
}
catch {
Write-Warning "Reg key edit error [$reg_key] [$name]"
}
}
}
Catch {
Write-Error "Check permissions to files or registry."
}
}

Данный скрипт получает фотографию текущего пользователя из Active Directory и сохраняет его на диск в разных разрешениях (фото в каталог
C:UsersPublicAccountPictures{SID пользователя})
. В каталоге будут содержаться JPG файлы с разными разрешениями (от 32×32 до 448×448 пикселя) под разные форматы элементов интерфейса Windows: image32.jpg, image40.jpg и т.п.

фото пользователя Windows через каталог AccountPictures

Чтобы привязать эти файлы фото к профилю пользователя осуществляется в ветке реестра, скрипт создаст сопоставления в разделе реестра
HKLMSOFTWAREMicrosoftWindowsCurrentVersionAccountPictureUsers{SID пользователя}
.

reestr HKLMSOFTWAREMicrosoftWindowsCurrentVersionAccountPictureUsers фото для профиля пользователя

Скопируйте код скрипта PowerShell и сохраните в новый PS1 файл на контроллер домена в каталог NetLogon (
winitpro.ruNETLOGONSetADPicture.ps1
)

Теперь нужно настроить запуск этого скрипта при входе пользователя в Windows. Проще всего это реализовать через логон скрипт группой политики.

Для этого в ранее созданной ранее политики в разделе User Configuration -> Policies -> Windows Settings -> Scripts (Logon/Logoff). Выберите Logon и перейдите на вкладку PowerShell Scripts:

Укажите полный UNC путь к файлу SetADPicture.ps1 в NETLOGON.

запуск логон скрипта gpo который настроит аватар пользователя в windows

Чтобы применить новые настройки GPO и загрузить фото из Active Directory в профиль Windows нужно перезайти в систему logoff и logon (дважды).

Проверьте, что фото пользователя из AD теперь отображается на экране входа в Windows и в других элементах интерфейса, например, на вкладке с информацией о пользователе в панели Settings (команда быстрого доступа
ms-settings:accounts
).

windows: аватара пользователя из active directory

 

Если политика не отработала:

  1. Если Windows не активирована, она не отображает аватар пользователя (проверить статус активации Windows на компьютерах);
  2. Проверьте что в настройках результирующей GPO на компьютере не включен параметр Apply the default logon picture to all users (Computer Settings-> Policies-> Administrative Templates-> Control Panel-> User Accounts);gpo: account picture по умолчанию в windows
  3. Выполните диагностику применения GPO на целевых компьютерах с помощью утилиты gpresult и рекомендаций из статьи “Почему не применяется GPO?”. [/alert]
Вы можете использовать данный PowerShell скрипт для настройки фото пользователей в Windows для всех поддерживаемых операционных систем: Windows 11, 10, 8.1 и Windows Server 2022,2019,2016 (поддерживаются в том числе сценарии с фото профилей пользователей на отдельностоящих хостах с ролью RDSH или Remote Desktop Services фермах).

PowerShell
Используем фото Active Directory для профиля пользователя Windows