Aktionen

ZnilTools:ImportThumbnailPhoto.exe

Aus znilwiki

Changelog:

  • 06.11.2017 : Erste Version 1.0.0.15

Download: ImportThumbnailPhoto.zip


1 Was macht es?

Dem Tool ImportThumbnailPhoto.exe kann man entweder einen Benutzernamen + Bilddatei übergeben. Dann wird das Bild dieses Benutzers geändert.
Oder gleich einen Ordner mit Bildern.
Die Bilder in dem Ordner müssen das Schema

sAMAccountName.png
oder
sAMAccountName.jpg

haben. das Tool sucht für jeden Dateinamen nach einen passenden Active Directory Benutzer.


2 Voraussetzungen

  • Muss innerhalb der Domäne ausgeführt werden in die Bilder gesetzt werden sollen
  • Muss Benutzer mit Berechtigung zum Ändern der AD-Konten sein (Domänen-Administrator)
  • Bilder maximal 100KByte
  • Bilder nicht zu groß und quadratisch. 300x300 Pixel scheint eine gute Größe zu sein



3 Programmhilfe

C:\_AutoIt\Active Directory\ProfilePicture>ImportThumbnailPhoto.exe
+------------------------------------------------------------------------------
| ImportThumbnailPhoto - Version 1.0.0.15
+------------------------------------------------------------------------------
| 2017/18 by Bernhard Linz for http://znil.net - Contact: Bernhard@znil.net
+------------------------------------------------------------------------------

Importiert .jpg oder .png mit einer Größe von maximal 100KByte in
das Active-Directory Attribut 'tumbnailPhoto' eines Benutzers.

Change single User-Photo:
-------------------------
ImportThumbnailPhoto.exe [sAMAccountName] [Path_to_jpg_org_png]
 [sAMAccountName]      : Login-Name of User like 'Max.Mustermann'
 [Path_to_jpg_org_png] : Path like 'D:\Pictures\Mustermann.png'
                         or '\\Server\Share\Folder\Mustermann.png'

Bulk import Photos:
-------------------
ImportThumbnailPhoto.exe [Path_to_Folder]
 [Path_to_Folder]      : Folder will scan for all .jpg and .png
                         Use Name-Schema 'sAMAccountName.jpg' or
                         'sAMAccountName.png'. Tool will search for
                         AD-Account for every Photo and Update the
                         thumbnailPhoto Attribut

+------------------------------------------------------------------------------
| ImportThumbnailPhoto.exe is FREEWARE! Copy and use explicitly allowed!
| The latest version and instructions can be found at:
| https://znil.net/index.php?title=ZnilTools:ImportThumbnailPhoto.exe
+------------------------------------------------------------------------------



4 Beispielausgabe

Einzelner Benutzer:

C:\_AutoIt\Active Directory\ProfilePicture>ImportThumbnailPhoto.exe Bernhard D:\Dropbox\Icons\Face-Avatars-by-deleket\Males\A05.png
Updated: Bernhard <== D:\Dropbox\Icons\Face-Avatars-by-deleket\Males\A05.png



Ordnerimport:

C:\_AutoIt\Active Directory\ProfilePicture>ImportThumbnailPhoto.exe \\DC02\Netlogon\thumbnailPhoto
Photos / User found: 7

 Status   sAMAccountName                     Path fo Photo
-------------------------------------------------------------------------------
 OK       andre.krueger                  <== \\DC02\Netlogon\thumbnailPhoto\andre.krueger.png
 OK       Bernhard                       <== \\DC02\Netlogon\thumbnailPhoto\Bernhard.png
 OK       Margarethe.Minderman           <== \\DC02\Netlogon\thumbnailPhoto\Margarethe.Minderman.png
 OK       Silke.Landwehr                 <== \\DC02\Netlogon\thumbnailPhoto\Silke.Landwehr.png
 OK       thomas.landwehr                <== \\DC02\Netlogon\thumbnailPhoto\thomas.landwehr.png
 NoUser   Unbekannter.Name               <== \\DC02\Netlogon\thumbnailPhoto\Unbekannter.Name.png
 OK       Yasmin                         <== \\DC02\Netlogon\thumbnailPhoto\Yasmin.png


5 Download

Beinhaltet die .exe, den Quellcode + UDF sowie das Icon:
Download: ImportThumbnailPhoto.zip


6 Quellcode

#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_Icon=Icon256-32.ico
#AutoIt3Wrapper_Change2CUI=y
#AutoIt3Wrapper_Res_Fileversion=1.0.0.16
#AutoIt3Wrapper_Res_Fileversion_AutoIncrement=y
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
Opt('MustDeclareVars', 1)
#include "AD.au3"
#include <Array.au3>
#include <File.au3>



Global $s_sAMAccountName = ""
Global $s_PhotoPath = ""
Global $a_s_PictureFilenames[1]
Global $h_Picture
Global $s_Picture

;                             10        20        30        40        50        60        70        80
;         			 12345678901234567890123456789012345678901234567890123456789012345678901234567890
Global $Header = 	"+------------------------------------------------------------------------------" & @CRLF & _
					"| ImportThumbnailPhoto - Version " & FileGetVersion(@ScriptName) & @CRLF & _
					"+------------------------------------------------------------------------------" & @CRLF & _
					"| 2017/18 by Bernhard Linz for http://znil.net - Contact: Bernhard@znil.net" & @CRLF & _
					"+------------------------------------------------------------------------------" & @CRLF & _
					@CRLF

;                                10        20        30        40        50        60        70        80
;                 	  	 12345678901234567890123456789012345678901234567890123456789012345678901234567890
Global $HilfeText = 	"Importiert .jpg oder .png mit einer Größe von maximal 100KByte in" & @CRLF & _
						"das Active-Directory Attribut 'tumbnailPhoto' eines Benutzers." & @CRLF & _
						@CRLF & _
						"Change single User-Photo:" & @CRLF & _
						"-------------------------" & @CRLF & _
						"ImportThumbnailPhoto.exe [sAMAccountName] [Path_to_jpg_org_png]" & @CRLF & _
						" [sAMAccountName]      : Login-Name of User like 'Max.Mustermann'" & @CRLF & _
						" [Path_to_jpg_org_png] : Path like 'D:\Pictures\Mustermann.png'" & @CRLF & _
						"                         or '\\Server\Share\Folder\Mustermann.png'" & @CRLF & _
						@CRLF & _
						"Bulk import Photos:" & @CRLF & _
						"-------------------" & @CRLF & _
						"ImportThumbnailPhoto.exe [Path_to_Folder]" & @CRLF & _
						" [Path_to_Folder]      : Folder will scan for all .jpg and .png" & @CRLF & _
						"                         Use Name-Schema 'sAMAccountName.jpg' or" & @CRLF & _
						"                         'sAMAccountName.png'. Tool will search for" & @CRLF & _
						"                         AD-Account for every Photo and Update the" & @CRLF & _
						"                         thumbnailPhoto Attribut" & @CRLF & _
						@CRLF & _
						"+------------------------------------------------------------------------------" & @CRLF & _
						"| ImportThumbnailPhoto.exe is FREEWARE! Copy and use explicitly allowed!" & @CRLF & _
						"| The latest version and instructions can be found at:" & @CRLF & _
						"| https://znil.net/index.php?title=ZnilTools:ImportThumbnailPhoto.exe" & @CRLF & _
						"+------------------------------------------------------------------------------" & @CRLF

; ###################################################################################
; F U N C T I O N E N / S U B R O U T I N E N
; ###################################################################################

; ###################################################################################
; _ANSI2OEM löst das Problem mit dem Umlauten und anderen Sonderzeichen. Es wandelt Text so um das er korrekt in der DOS-Box dargestellt wird
; So können hier im Quellcode auch Umlaute verwendet werden (in den Textausgaben) und diese werden dann korrekt dargestellt
; Wir zudem für die Prüfung der Gruppenzugehörigkeit benötigt für Gruppen mit Umlauten, z.B. Domänen-Admins
; Dank an Xenobiologist von AutoIt.de für diese Lösung: http://www.autoit.de/index.php?page=Thread&threadID=9461&highlight=ANSI2OEM

Func _ANSI2OEM($text)
	$text = DllCall('user32.dll', 'Int', 'CharToOem', 'str', $text, 'str', '')
	Return $text[2]
	;Return $text
EndFunc   ;==>_ANSI2OEM

; ###################################################################################
; Hilfsroutine die den Hilfetext ausgibt
Func _HilfeAusgeben()
	;_WinAPI_AttachConsole()
	;$ZeigerConsole = _WinAPI_GetStdHandle(1)
	ConsoleWrite(_ANSI2OEM($Header))
	ConsoleWrite(_ANSI2OEM($HilfeText))
	;_WinAPI_AttachConsole()
	;$ZeigerConsole = _WinAPI_GetStdHandle(1)
	;_WinAPI_WriteConsole($ZeigerConsole,$Header)
	;_WinAPI_WriteConsole($ZeigerConsole,$HilfeText)
	;_WinAPI_WriteConsole($ZeigerConsole,@CRLF)
	;Send("{Enter}")
EndFunc   ;==>_HilfeAusgeben

; ###################################################################################
; Hilfsroutine damit ich nicht jedesmal das ANSI2OEM und das @CRLF im Code eingeben muss
Func _MeldungAusgebenConsole($Meldungstext)
	ConsoleWrite(_ANSI2OEM($Meldungstext) & @CRLF)
	;_WinAPI_AttachConsole()
	;$ZeigerConsole = _WinAPI_GetStdHandle(1)
	;_WinAPI_WriteConsole($ZeigerConsole, $Fehlertext)
	;Send("{Enter}")
EndFunc   ;==>_MeldungAusgebenConsole

; ###################################################################################
; Im Prinzip das selbe wie MeldungAusgebenConsole - ich fand die Fehlermeldungen aber
; zu unauffällig und habe diese hiermit auffälliger gestaltet
Func _FehlerAusgeben($FehlerUeberschrift, $Fehlertext)
	;_WinAPI_AttachConsole()
	;$ZeigerConsole = _WinAPI_GetStdHandle(1)
	ConsoleWrite("+----------------------------------------------------------------------------" & @CRLF)
	ConsoleWrite("| " & _ANSI2OEM($FehlerUeberschrift) & @CRLF)
	ConsoleWrite("+------------------------------------------------------------------------------" & @CRLF)
	ConsoleWrite("| " & _ANSI2OEM($Fehlertext) & @CRLF)
	ConsoleWrite("+------------------------------------------------------------------------------" & @CRLF)
EndFunc   ;==>_FehlerAusgeben

; ###############################################################################################################################################################################################
;~       ____                          _           _____ _ _      _     _     _  _____       _
;~      |  _ \ ___  ___ _   _ _ __ ___(_)_   _____|  ___(_) | ___| |   (_)___| ||_   _|__   / \   _ __ _ __ __ _ _   _
;~      | |_) / _ \/ __| | | | '__/ __| \ \ / / _ \ |_  | | |/ _ \ |   | / __| __|| |/ _ \ / _ \ | '__| '__/ _` | | | |
;~      |  _ <  __/ (__| |_| | |  \__ \ |\ V /  __/  _| | | |  __/ |___| \__ \ |_ | | (_) / ___ \| |  | | | (_| | |_| |
;~  ____|_| \_\___|\___|\__,_|_|  |___/_| \_/ \___|_|   |_|_|\___|_____|_|___/\__||_|\___/_/   \_\_|  |_|  \__,_|\__, |
;~ |_____|                                                                                                       |___/
;===============================================================================
; Function Name:   _RecursiveFileListToArray($sPath[, $sPattern][, $iFlag][, $iFormat][, $fRecursion][, $sDelim])
; Description::    gibt Verzeichnisse (rekursiv) und/oder Dateien zurück, die einem RegExp-Pattern entsprechen
; Parameter(s):    $sPath = Startverzeichnis
;                  $sPattern = ein beliebiges RexExp-Pattern für die Auswahl
;                  $iFlag = Auswahl
;                           0 = Dateien & Verzeichnisse
;                           1 = nur Dateien
;                           2 = nur Verzeichnisse
;                  $iFormat = Rückgabeformat
;                             0 = String
;                             1 = Array mit [0] = Anzahl
;                             2 = Nullbasiertes Array
;                  $fRecursion = Verzeichnisse rekursiv durchsuchen
;                                False = Nein
;                                True = Ja
;                  $sDelim = Trennzeichen für die String-Rückgabe
; Requirement(s):  AutoIt 3.3.0.0
; Return Value(s): Array/String mit den gefundenen Dateien/Verzeichnissen
; Author(s):       Oscar (www.autoit.de)
;                  Anregungen von: bernd670 (www.autoit.de)
;                             und: AspirinJunkie (www.autoit.de)
;===============================================================================
; Oscars Funktion ist 4x schneller als das was ich sonst benutzt habe (bei 6000 Dateien statt 2 sec nur 0,05 sec)
Func _RecursiveFileListToArray($sPath, $sPattern = '', $iFlag = 0, $iFormat = 1, $fRecursion = True, $sDelim = @CRLF, $fOpenDLL = True)
	Local $hSearch, $sFile, $sReturn = '', $aD
	Local Static $hDll
	If StringRight($sPath, 1) <> '\' Then $sPath &= '\'
	$hSearch = FileFindFirstFile($sPath & '*')
	If @error Or $hSearch = -1 Then Return SetError(1, 0, $sReturn)
	If $fOpenDLL Then $hDll = DllOpen('kernel32.dll')
	While True
		$sFile = FileFindNextFile($hSearch)
		If @error Then ExitLoop
		If @extended Then
			$aD = DllCall($hDll, 'dword', 'GetFileAttributesW', 'wstr', $sPath & $sFile)
			If @error Or BitAND($aD[0], 0x400) Then ContinueLoop
			If StringRegExp($sPath & $sFile, $sPattern) And ($iFlag = 0 Or $iFlag = 2) Then $sReturn &= $sPath & $sFile & '\' & $sDelim
			If $fRecursion Then $sReturn &= _RecursiveFileListToArray($sPath & $sFile & '\', $sPattern, $iFlag, 0, True, $sDelim, False)
			ContinueLoop
		EndIf
		If StringRegExp($sFile, $sPattern) And ($iFlag = 0 Or $iFlag = 1) Then $sReturn &= $sPath & $sFile & $sDelim
	WEnd
	FileClose($hSearch)
	If $fOpenDLL Then DllClose($hDll)
	If $iFormat And $sReturn = '' Then Return SetError(0, 1, StringSplit($sReturn, '', $iFormat))
	If $iFormat Then Return SetError(0, 2, StringSplit(StringTrimRight($sReturn, StringLen($sDelim)), $sDelim, $iFormat))
	Return $sReturn
EndFunc   ;==>_RecursiveFileListToArray

; ######################################################################################################################################################################
; ######################################################################################################################################################################
; ######################################################################################################################################################################
; H A U P T P R O G R A M M
; ######################################################################################################################################################################
; ######################################################################################################################################################################
; ######################################################################################################################################################################






; ###################################################################################
; H I L F E
; ###################################################################################

;testen ob wir überhaupt mit einem Parameter gestartet wurden - sonst Hilfe ausgeben
If $CmdLine[0] = 0 Then
	_HilfeAusgeben()
	Exit
EndIf

;testen ob der Parameter 1 ist auf "/?" testen und ebenfalls Hilfe ausgeben
If $CmdLine[1] = "/?" Then
	_HilfeAusgeben()
	Exit
EndIf

; ###################################################################################
; Benutzer <== Bild
; ###################################################################################
; Testen ob es 2 Parameter sind und entsprechend handeln:
If $CmdLine[0] = 2 Then
	$s_sAMAccountName = $CmdLine[1]
	$s_PhotoPath = $CmdLine[2]
	; Testen ob es das Bild überhaupt gibt:
	If FileExists($s_PhotoPath) = 0 Then
		_FehlerAusgeben("File not found:", $s_PhotoPath)
		Exit 1
	EndIf
	; Testen ob .jpg oder .png
	If StringRight($s_PhotoPath, 4) <> ".jpg" And StringRight($s_PhotoPath, 4) <> ".png" Then
		_FehlerAusgeben("File is not .jpg or .png:", $s_PhotoPath)
		Exit 1
	EndIf
	; Dateigröße testen:
	If FileGetSize($s_PhotoPath) > 102400 Then
		_FehlerAusgeben("File greater than 100KByte:", $s_PhotoPath)
		Exit 1
	EndIf
	; Ok, Datei ist in Ordnung - einlesen!
	$h_Picture = FileOpen($s_PhotoPath, 16)
	If $h_Picture = (-1) Then
		_FehlerAusgeben("Unable to open file:", $s_PhotoPath)
		Exit 1
	EndIf
	$s_Picture = FileRead($h_Picture)
	FileClose($h_Picture)
	; Jetzt dem Benutzer aktualisieren
	_AD_Open()
	Local $i_Return = _AD_ModifyAttribute($s_sAMAccountName,"thumbnailPhoto",$s_Picture)
	If $i_Return = 1 Then
		_MeldungAusgebenConsole("Updated: " & $s_sAMAccountName & " <== " & $s_PhotoPath)
		_AD_Close()
		Exit 0
	Else
		_FehlerAusgeben("User not found or AD-Error:", $s_sAMAccountName)
		_AD_Close()
		Exit 1
	EndIf
EndIf

; ###################################################################################
; Ordner mit Bildern => Benutzer
; ###################################################################################
; Testen ob es 1 Parameter ist und entsprechend handeln:
If $CmdLine[0] = 1 Then
	$s_PhotoPath = $CmdLine[1]
	; Ggf. Backslash am Ende abschneiden
	If StringRight($s_PhotoPath,1) = "\" Then
		StringTrimRight($s_PhotoPath, 1)
	EndIf
	; Testen ob es den Ordner überhaupt gibt:
	If FileExists($s_PhotoPath) = 0 Then
		_FehlerAusgeben("Folder / File not found:", $s_PhotoPath)
		Exit 1
	EndIf
	; Liste mit den Bildern erstellen:
	$a_s_PictureFilenames = _RecursiveFileListToArray($s_PhotoPath, '(?m)(?i).+\.(' & "JPG|PNG" & ')$', 1, 1, True)
;~ 	_ArrayDisplay($a_s_PictureFilenames)
	If $a_s_PictureFilenames[0] = 0 Then
		_FehlerAusgeben("No *.jpg or *.png Photos in path found", $s_PhotoPath)
		Exit 0
	EndIf
	Local $_s_empty = ""
	_MeldungAusgebenConsole("Photos / User found: " & $a_s_PictureFilenames[0])
	ConsoleWrite(@CRLF)
	;                        12345678901234567890123456789012345678901234567890123456789012345678901234567890
	_MeldungAusgebenConsole(" Status   sAMAccountName                     Path fo Photo")
	_MeldungAusgebenConsole("-------------------------------------------------------------------------------")
	_AD_Open()
	For $i = 1 To $a_s_PictureFilenames[0] Step 1
		; Wir dröseln den Pfad des Bildes auseinander
		Local $_a_PathSplit = _PathSplit($a_s_PictureFilenames[$i], $_s_empty, $_s_empty, $_s_empty, $_s_empty)
		$s_sAMAccountName = $_a_PathSplit[3] ; Dateiname
		$h_Picture = ""
		$s_Picture = ""
		; Dateigröße!
		If FileGetSize($a_s_PictureFilenames[$i]) < 102400 Then
			$h_Picture = FileOpen($a_s_PictureFilenames[$i], 16)
			If $h_Picture = (-1) Then
				ConsoleWrite(" FileOpen ")
			Else
				$s_Picture = FileRead($h_Picture)
				FileClose($h_Picture)
				If $s_Picture = "" Then
					Local $i_Return = _AD_ModifyAttribute($s_sAMAccountName,"thumbnailPhoto", "")
					ConsoleWrite(" NotRead  ")
				Else
					Local $i_Return = _AD_ModifyAttribute($s_sAMAccountName,"thumbnailPhoto", $s_Picture)
				EndIf
				If $i_Return = 1 Then
					;             1234567890
					ConsoleWrite(" OK       ")
				Else
					ConsoleWrite(" NoUser   ")

				EndIf
			EndIf
		Else
			ConsoleWrite(" FileSize ")
		EndIf
		_MeldungAusgebenConsole(StringFormat("%-30s", $s_sAMAccountName) & " <== " & $a_s_PictureFilenames[$i])
	Next
	Exit 0
EndIf



7 Kommentare


Kommentar hinzufügen
znilwiki freut sich über alle Kommentare. Sofern du nicht anonym bleiben möchtest, trage deinen Namen oder deine Email-Adresse ein oder melde dich an. Du kannst das Feld auch einfach leer lassen.