افزودن عکس کاربران شبکه در پروفایل ویندوز

کامپیوتر و موبایل

به سفارش جناب آقای مقدسی، باید اسکریپتی را تهیه می کردم که تصویر هر کاربر، در ویندوزی که لاگین می کند، نمایش داده شود.

این تصویر، تصویر پیش فرض لاگین کاربران است.

 

در مرحله بعد مقادیر اصلی را باید وارد کرد. می توانید مقادیر اصلی را الان وارد نکرده و در زمان دلخواه توسط Action های InfoPath وارد کنید. که ما هم همین کار را انجام می دهیم. پس این مرحله را رد می کنیم.

اصل ماجرا چیست؟

در این سازمان، اطلاعات پرسنل، در نرم افزار اتوماسیون اداری ثبت می شود. در این نرم افزار، کاربران با شماره پرسنلی وارد می شوند و شناخته می شوند.

برای ارتباط بین نرم افزار اتوماسیون اداری و Active Directory، شماره پرسنلی در attribute ی به نام employeeid ذخیره می شود.

راه حل چیست؟

مرحله اول

ابتدا نیاز به یک نرم افزار تحت وب مختصر داریم که با گرفتن شماره پرسنلی، عکس کارمند را به ما بدهد. برای پرتال تحت SharePoint این نیاز بود و من قبلا این بخش را آماده کرده بودم:

http://sharepoint:81/employee-pic.aspx?pid=6007

خروجی این آدرس، یک عکس خواهد بود.

مرحله دوم

در مراحل بعد، باید اسکریپتی تهیه شود که:

  • در زمان لاگین یا لاگ آف کاربر، کد پرسنلی را از Active Directory بخواهند.
  • با استفاده از URL بالا، فایل تصویر را از اتوماسیون بخواند.
  • در Registery کلاینت، فایل (های) تصویر کاربر را ذخیره کند.

چون ما با رجیستری کار می کنیم، ابتدا باید دسترسی های لازم را به بخش مورد نظر برای کاربران تعریف کنیم:

در Group Policy Management مسیر زیر را باز کنید:

Computer Configuration > Policies > Windows Settings > Security Settings

روی Registry کلیک راست کرده و گزینه Add Keyرا بزنید.

در قسمت Selected Key این متن را وارید کنید. در درخت بالایی، شاخه مورد نظر انتخاب می شود:

MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\AccountPicture\Users

و سپس OK را کلیک کنید:

در قسمت Selected Key این متن را وارید کنید. در درخت بالایی، شاخه مورد نظر انتخاب می شود:

MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\AccountPicture\Users

و سپس OK را کلیک کنید:

در مرحله آخر تیک گزینه Automatically retrieve… را بر می داریم. چرا که اینکار باعث می شود، تابع اجرا شده و مقادیر را الان بر می گرداند. ولی ما در برنامه هر گاه خواستیم از این تابع استفاده کنیم، مقادیر را توسط Action های InfoPath دریافت خواهیم کرد.

بعد از تایید این پنجره، پنجره دیگری باز می شود که شما باید گزینه زیر را انتخاب کنید:

پس ما در این مرحله، دسترسی کامل به ذخیره تنظیمات کاربر در رجیستری را به کاربران دادیم.

مرحله سوم

در این مرحله باید اسکریپتی بسازیم که:

  • با استفاده از URL بالا، فایل تصویر را از اتوماسیون بخواند.
  • در Registery کلاینت، فایل (های) تصویر کاربر را ذخیره کند.

متن کد زیر را در یک فایل با پسوند ps1 ذخیره کرده و جایی روی شبکه ذخیره کنید. جایی که همه کاربران به آن دسترسی داشته باشند مثل:

%logonserver%\netlogon

متن کد

[CmdletBinding(SupportsShouldProcess=$true)]Param()

function Test-Null($InputObject) { return !([bool]$InputObject) }

Function ResizeImage()

{

param([String]$ImagePath, [Int]$Quality = 90, [Int]$targetSize, [String]$OutputLocation)

Add-Type -AssemblyName “System.Drawing”

$img = [System.Drawing.Image]::FromFile($ImagePath)

$CanvasWidth = $targetSize

$CanvasHeight = $targetSize

#Encoder parameter for image quality

$ImageEncoder = [System.Drawing.Imaging.Encoder]::Quality

$encoderParams = New-Object System.Drawing.Imaging.EncoderParameters(1)

$encoderParams.Param[0] = New-Object System.Drawing.Imaging.EncoderParameter($ImageEncoder, $Quality)

# get codec

$Codec = [System.Drawing.Imaging.ImageCodecInfo]::GetImageEncoders() | Where {$_.MimeType -eq ‘image/jpeg’}

#compute the final ratio to use

$ratioX = $CanvasWidth / $img.Width;

$ratioY = $CanvasHeight / $img.Height;

$ratio = $ratioY

if ($ratioX -le $ratioY) {

$ratio = $ratioX

}

$newWidth = [int] ($img.Width * $ratio)

$newHeight = [int] ($img.Height * $ratio)

$bmpResized = New-Object System.Drawing.Bitmap($newWidth, $newHeight)

$graph = [System.Drawing.Graphics]::FromImage($bmpResized)

$graph.InterpolationMode = [System.Drawing.Drawing2D.InterpolationMode]::HighQualityBicubic

$graph.Clear([System.Drawing.Color]::White)

$graph.DrawImage($img, 0, 0, $newWidth, $newHeight)

#save to file

$bmpResized.Save($OutputLocation, $Codec, $($encoderParams))

$bmpResized.Dispose()

$img.Dispose()

}

###############################################################################

#get sid and photo for current user

$user_sid = [System.Security.Principal.WindowsIdentity]::GetCurrent().User.Value

$user = ([ADSISearcher]”(&(objectCategory=User)(SAMAccountName=$env:username))”).FindOne().Properties

$employid = $user.employeeid

if ((Test-Null @employid) -eq $false)

{

$url = “http://sharepoint:81/employee-pic.aspx?pid=$employid

#create hidden directory, if it doesn’t exist

$image_base = “C:\ProgramData\AccountPictures”

$dir = $image_base + “\” + $user_sid

If ((Test-Path -Path $dir) -eq $false) { $(mkdir $dir).Attributes = “Hidden” }

$fname = “$image_base\$employid.png”

Invoke-WebRequest $url -OutFile $fname

#$user_photo = $user.thumbnailphoto

$user_photo = Get-Content -Path $fname -Encoding Byte

#continue if an image was returned

If ((Test-Null $user_photo) -eq $false)

{

Write-Verbose “Success. Photo exists.”

#set up image sizes and base path

$image_sizes = @(32, 40, 48, 96, 192, 200, 240, 448)

$image_mask = “Image{0}.jpg”

#set up registry

$reg_base = “HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\AccountPicture\Users\{0}”

$reg_key = [string]::format($reg_base, $user_sid)

$reg_value_mask = “Image{0}”

If ((Test-Path -Path $reg_key) -eq $false)

{

New-Item -Path $reg_key

}

#save images, set reg keys

ForEach ($size in $image_sizes)

{

#save photo to disk, overwrite existing files

$file_name = ([string]::format($image_mask, $size))

$pathtmp = $dir + “\_” + $file_name

$path = $dir + “\” + $file_name

Write-Verbose ” saving: $file_name”

$user_photo | Set-Content -Path $pathtmp -Encoding Byte -Force

ResizeImage $pathtmp $size $size $path

Remove-Item $pathtmp

#save the path in registry, overwrite existing entries

$name = [string]::format($reg_value_mask, $size)

$value = New-ItemProperty -Path $reg_key -Name $name -Value $path -Force

}

Write-Verbose “Done.”

}

else

{

Write-Error “No photo found for $env:username”

}

}

توضیح

از Active Directory مقدار صفت employeeid مربوط به کاربر جاری خوانده می شود. آدرس URL بالا که تصویر کارمند را ارائه می دهد با کد کارمند ساخته می شود. از آدرس ساخته شده، فایل عکس دانلود می شود. نسخه های مختلف مورد نیاز در اندازه های مختلف ساخته می شود. همه تصاویر کاربر در آدرس زیر ذخیره می شوند:

 

C:\ProgramData\AccountPictures

در مرحله بعد، آدرس عکس ها در رجیستری، در مسیری که بیان شد ثبت می شوند.

مرحله چهارم

 

می خواهیم یک Policy در دامین بسازیم که کد ساخته شده را در زمان لاگ آف کاربر اجرا کند. کجا برویم؟ Group Plicy Mangement. کجا؟ روی سرور Domain Controller

طبق تصویر زیر پالیسی را می سازیم:

یک نام به آن می دهیم. Edit را زده و در پنجره Group Policy Management Editor در آدرس زیر:

User Configuration > Policies > Windows Settings > Scripts (Logon/Logoff)

روی Logoff دابل کلیک می کنیم:

طبق تصویر زیر، آدرس فایل اسکریپتی که ذخیره کرده ایم را می دهیم:

و پایان.

اکنون با اعمال پالیسی ساخته شده روی کلاینتها، این اسکریپت روی کلاینت اجرا می شود. دفعه بعد که کاربر لاگین کند، تصویر خود را می بیند.

مرجع:

https://www.codetwo.com/admins-blog/use-active-directory-user-photos-windows-10/