Search the Community
Showing results for tags 'avatar'.
-
Automate the change of the (current) user account picture was a script that I was missing, but I was sure to find an easy command line, like a simple powershell. It was not the case, I found only methods to change it in Active Directory environments, and my goal was to change the account picture also in freshly installed win 10/11 non domain OSes, and it works also in domain machines. The focus is to take care of every aspect of the process. The code: #Region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_Icon=Icone\angryRabbit.ico #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** ;UAP ;User Account Picture ;()NSC 2023 ;notes ; only way to access 64-bit node in a 32-bit compiled script is using HKLM64 ;Computer\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\AccountPicture\Users ;main inspiration ;https://social.msdn.microsoft.com/Forums/sqlserver/en-US/3f50b25a-4c47-4bc8-959e-1108419288a7/how-to-set-specific-users-account-picture-from-cmd?forum=scripting ;PSexec to use as System '-s' switch ;https://learn.microsoft.com/it-it/sysinternals/downloads/psexec ;image processing ;https://imagemagick.org/index.php ;https://imagemagick.org/script/command-line-processing.php ;needed VCredist ;https://learn.microsoft.com/it-it/cpp/windows/latest-supported-vc-redist?view=msvc-170 ;https://aka.ms/vs/17/release/vc_redist.x64.exe ;permissions SETACL ;https://helgeklein.com/setacl/ ;https://www.autoitscript.com/forum/topic/162656-change-registry-key-permissions/?do=findComment&comment=1182956 ;interesting but not used (AD related) ;https://woshub.com/how-to-set-windows-user-account-picture-from-active-directory/ #RequireAdmin #include <Security.au3> #include <Array.au3> #include <File.au3> #include <String.au3> #include <_Gollog.au3> $mygui = "UAP - NSC 2023" gollog_ini($mygui, 600, 300, 200, 200, "0x050980", "0xf2dcc3", "consolas") ;f2dcc3 Global $tempfolder = "c:\temp", $ver = "V.1.0" Global $onlyexe4conversion = "magick.exe", $exe4conversion = $tempfolder & "\" & $onlyexe4conversion Global $onlyexe4regperm = "setacl.exe", $exe4regperm = $tempfolder & "\" & $onlyexe4regperm Global $onlyexe4PsExec = "psexec64.exe", $exe4PsExec = $tempfolder & "\" & $onlyexe4PsExec Global $vcredist = $tempfolder & "\" & "VC_redist.x64.exe" Global $registrypath = "hklm64\SOFTWARE\Microsoft\Windows\CurrentVersion\AccountPicture\Users\" Global $registrypath4SETACL = "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\AccountPicture\Users\" Global $aSizes[11] = ["32x32", "40x40", "48x48", "64x64", "96x96", "192x192", "208x208", "240x240", "424x424", "448x448", "1080x1080"] Gollog("START UAP " & $ver) Global $sConsoleUser = _GetConsoleUser() Gollog("Console User: " & $sConsoleUser & @CRLF) Global $aUserProfile = _GetProfile($sConsoleUser) Gollog("Console User Path: " & $aUserProfile[1][1] & @CRLF) Global $folder4accountPictures = $aUserProfile[1][1] & "\" & "UAP" ;_ArrayDisplay($aUserProfile, "current USER") Global $aexpprof = _StringExplode($aUserProfile[1][2], "\") Global $CUreg = $aexpprof[UBound($aexpprof) - 1] Gollog("current user SID: " & $CUreg & @CRLF) ;TEST all users Gollog("enumerating all users:") Global $allUserProfiles = _GetProfile() For $i = 1 To UBound($allUserProfiles) - 1 Gollog($allUserProfiles[$i][0] & " " & $allUserProfiles[$i][2]) Next ;_ArrayDisplay($allUserProfiles, "all USERS") createFolder4userPictures() TempCreate() SetRegPermissions() VcRedist() GenPicS() Gollog("END UAP") Func GenPicS() ;image prepare Gollog("picking image for avatar") Local $sourceimg = FileOpenDialog("Select Image for your User Profile", @UserProfileDir & "\" & "downloads", "Images (*.png;*.jpg;*.jpeg;*.gif;*.bmp)", 1) Local $sDrive = "", $sDir = "", $sFileName = "", $sExtension = "" Local $aPathSplit = _PathSplit($sourceimg, $sDrive, $sDir, $sFileName, $sExtension) ;registry prepare If RegDelete($registrypath & $CUreg) Then Gollog("regdelete ok " & @CRLF) Gollog($registrypath & $CUreg & @CRLF) Else Gollog("regdelete error " & @error & @CRLF) Gollog($registrypath & $CUreg & @CRLF) EndIf If RegWrite($registrypath & $CUreg) Then Gollog("regwrite root ok " & @CRLF) Else Gollog("regwrite root error " & @error & @CRLF) EndIf For $i = 0 To UBound($aSizes) - 1 ;image conversion ShellExecuteWait($exe4conversion, $sourceimg & " -resize " & $aSizes[$i] & " " & $folder4accountPictures & "\" & $sFileName & "_" & $aSizes[$i] & $sExtension) ;registry write Local $apartsize = _StringExplode($aSizes[$i], "x") If RegWrite($registrypath & $CUreg, "Image" & $apartsize[0], "REG_SZ", $folder4accountPictures & "\" & $sFileName & "_" & $aSizes[$i] & $sExtension) Then Gollog("regewrite image ok " & $aSizes[$i] & @CRLF) Gollog($registrypath & $CUreg & " Image" & $apartsize[0] & " REG_SZ " & $folder4accountPictures & "\" & $sFileName & "_" & $aSizes[$i] & $sExtension) Else Gollog("regwrite image error " & @error & @CRLF) Gollog($registrypath & $CUreg & " Image" & $apartsize[0] & " REG_SZ " & $folder4accountPictures & "\" & $sFileName & "_" & $aSizes[$i] & $sExtension) EndIf Next EndFunc ;==>GenPicS Func VcRedist() Gollog("installing Microsoft Visual C++ Redistributable ") ShellExecuteWait($vcredist, "/install /passive /norestart") EndFunc ;==>VcRedist Func SetRegPermissions() Gollog("creating file to set registry permissions") ;writing bat file Local $batfile = $tempfolder & "\" & "UAPsetacl.bat" If FileExists($batfile) Then FileDelete($batfile) gollog("deleted old " & $batfile) EndIf Local $hFileOpen = FileOpen($batfile, $FO_APPEND) If $hFileOpen = -1 Then MsgBox($MB_SYSTEMMODAL, "", "An error occurred whilst writing the UAPsetacl.bat file", 3) GOLLOG("An error occurred whilst writing the UAPsetacl.bat file") Exit EndIf FileWriteLine($hFileOpen, 'c:\temp\setacl.exe -on "' & $registrypath4SETACL & $CUreg & '" -ot reg -actn ace -ace "n:Administrators;p:full"') FileClose($hFileOpen) Gollog("set registry permissions") ;launch permission set on registry ShellExecuteWait($exe4PsExec, " -s -accepteula " & $batfile) EndFunc ;==>SetRegPermissions Func TempCreate() Gollog("deploying necessary temp files") If Not FileExists($tempfolder) Then DirCreate($tempfolder) FileInstall("C:\nsc_TEST\resources\imagemagick\magick.exe", $exe4conversion, 1) FileInstall("C:\nsc_TEST\resources\SetACL\64 bit\setacl.exe", $exe4regperm, 1) FileInstall("C:\NSC_test\resources\PSExec\PsExec64.exe", $exe4PsExec, 1) FileInstall("C:\nsc_TEST\resources\VCredist\VC_redist.x64.exe", $vcredist, 1) EndFunc ;==>TempCreate ;Create folder for user pictures - cleaning pre existing Func createFolder4userPictures() Gollog("creating folder for new avatar pictures") If FileExists($folder4accountPictures & "\") Then DirRemove($folder4accountPictures, 1) EndIf DirCreate($folder4accountPictures) EndFunc ;==>createFolder4userPictures ;Use WMI query to get user logged onto console Func _GetConsoleUser() Local $objWMIService = ObjGet("winmgmts:{impersonationLevel=impersonate}!//.") Local $colUsers, $objUser Local $strAccount $colUsers = $objWMIService.InstancesOf("Win32_ComputerSystem") For $objUser In $colUsers $strAccount = $objUser.UserName Next If $strAccount <> "" Then Return $strAccount Else Return (1) EndIf EndFunc ;==>_GetConsoleUser ; #FUNCTION# ==================================================================================================================================== ; Name...........: _GetProfile ; Description ...: Determine each user's Profile folder, the user's SID and if the profile is loaded to the registry ; Syntax.........: _GetProfile([$sAccount, $sComputer]) ; Parameters ....: $sAccount - User account name, defaults to all users ; $sComputer - Computer name, the local computer is default ; Requirement(s).: Service 'RemoteRegistry' running on the target computer ; When the target computer is the local computer, the 'RemoteRegistry' service isn't required ; Return values .: An array containing the path to each user's profile folder, the user's SID ; The array returned is two-dimensional and is made up as follows: ; $array[0][0] = Number of profiles ; $array[1][0] = 1st user name ; $array[1][1] = Path to 1st user profile ; $array[1][2] = 1st user registry hive ; $array[1][3] = 1 if 1st user profile is loaded to the registry, 0 if not ; $array[2][0] = 2nd user name ; $array[2][1] = Path to 2nd user profile ; $array[2][2] = 2nd user registry hive ; $array[2][3] = 1 if 2nd user profile is loaded to the registry, 0 if not ; ... ; $array[n][0] = nth user name ; $array[n][1] = Path to nth user profile ; $array[n][2] = nth user registry hive ; $array[n][3] = 1 if nth user profile is loaded to the registry, 0 if not ; Author ........: engine ; Modified.......: AdamUL ; Remarks .......: ; Related .......: ; Link ..........; ; Example .......; _GetProfile("Default User") to get Default User's profile data on the local computer ; =============================================================================================================================================== Func _GetProfile($sAccount = "", $sComputer = @ComputerName) Local $avArray[1][4], $sDefaultUser, $sEnv Local Const $sProfileListKey = "\\" & $sComputer & "\HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList" Local Const $sRootKey = "\\" & $sComputer & "\HKEY_USERS\" Local Const $sDefaultUser1 = RegRead($sProfileListKey, "DefaultUserProfile") Local Const $iDefaultUser1Error = @error Local Const $sDefaultUser2 = RegRead($sProfileListKey, "Default") Local Const $iDefaultUser2Error = @error If $iDefaultUser1Error And $iDefaultUser2Error Then $avArray[0][0] = 0 Return $avArray EndIf If $iDefaultUser1Error Then $sDefaultUser = "Default" Else $sDefaultUser = $sDefaultUser1 EndIf If $sAccount = "" Or $sAccount = $sDefaultUser Then Local $iInstance, $sSID While 1 $iInstance += 1 $sSID = RegEnumKey($sProfileListKey, $iInstance) If @error Then ExitLoop If StringLen($sSID) > 8 Then ProfileAdd($avArray, $sSID, $sProfileListKey, $sRootKey) WEnd Local $u = UBound($avArray), $iSum For $k = 1 To $u - 1 $iSum += $avArray[$k][3] Next ReDim $avArray[$u + 1][4] $avArray[$u][0] = $sDefaultUser $avArray[$u][1] = RegRead($sProfileListKey, "ProfilesDirectory") & "\" & $sDefaultUser If $iSum = 0 Then $avArray[$u][2] = "\\" & $sComputer & "\HKEY_CURRENT_USER" $avArray[$u][3] = 1 Else Local $avDomain, $iN = 998, $sDSID, $avDU $avDomain = _Security__LookupAccountName($sComputer, $sComputer) Do $iN += 1 $sDSID = $avDomain[0] & "-" & $iN $avDU = _Security__LookupAccountSid($sDSID, $sComputer) Until $avDU = 0 $avArray[$u][2] = $sRootKey & $sDSID $avArray[$u][3] = 0 EndIf If $sAccount = $sDefaultUser Then Local $avNew[2][4] = [["", "", "", ""], [$avArray[$u][0], $avArray[$u][1], $avArray[$u][2], $avArray[$u][3]]] $avArray = $avNew EndIf Else Local $avSID = _Security__LookupAccountName($sAccount, $sComputer) If $avSID = 0 Then $avArray[0][0] = 0 Return $avArray Else ProfileAdd($avArray, $avSID[0], $sProfileListKey, $sRootKey) EndIf EndIf $avArray[0][0] = UBound($avArray) - 1 For $j = 1 To $avArray[0][0] $sEnv = StringRegExp($avArray[$j][1], "\x25\S{1,128}\x25", 1) If Not @error Then $avArray[$j][1] = StringReplace($avArray[$j][1], $sEnv[0], EnvGet(StringReplace($sEnv[0], "%", ""))) Next Return $avArray EndFunc ;==>_GetProfile ; #INTERNAL_USE_ONLY#============================================================================================================================ ; Name...........: ProfileAdd ; Description ...: Add profile data to an array that will be returned by _GetProfile function ; Syntax.........: ProfileAdd($avArray, $sSID, $sProfileListKey, $sRootKey) ; Parameters ....: $avArray - Array ; $sSID - Account SID ; $sProfileListKey - Constant defined inside _GetProfile function ; $sRootKey - Constant defined inside _GetProfile function ; Requirement(s).: ; Return values .: ; Author ........: engine ; Modified.......: AdamUL ; Remarks .......: For internal use only ; Related .......: ; Link ..........; ; Example .......; ; =============================================================================================================================================== Func ProfileAdd(ByRef $avArray, $sSID, Const $sProfileListKey, Const $sRootKey) Local $sPath, $i Local $asSplit = Split_sKey("\" & $sProfileListKey) Local $avUser = _Security__LookupAccountSid($sSID, $asSplit[0]) If Not @error And $avUser <> 0 Then If $avUser[2] = 1 Then $sPath = RegRead($sProfileListKey & "\" & $sSID, "ProfileImagePath") If Not @error Then $i = UBound($avArray) ReDim $avArray[$i + 1][4] $avArray[$i][0] = $avUser[0] $avArray[$i][1] = $sPath $avArray[$i][2] = $sRootKey & $sSID RegEnumKey($sRootKey & $sSID, 1) If @error Then $avArray[$i][3] = 0 Else $avArray[$i][3] = 1 EndIf EndIf EndIf EndIf EndFunc ;==>ProfileAdd ; #INTERNAL_USE_ONLY#============================================================================================================================ ; Name...........: Split_sKey ; Description ...: Splits $sKey between computername, username and keyname ; Syntax.........: Split_sKey($sKey) ; Parameters ....: $sKey - Reg function main key ; Requirement(s).: ; Return values .: ; Author ........: engine ; Modified.......: ; Remarks .......: For internal use only ; Related .......: ; Link ..........; ; Example .......; ; =============================================================================================================================================== Func Split_sKey($sKey) Local $asArray[3] If StringInStr($sKey, "\\\") = 1 Then Local $asComputer = StringRegExp($sKey, "\\\\\\[^\\]*\\", 1) If Not @error Then $asArray[0] = StringTrimRight(StringTrimLeft($asComputer[0], 3), 1) $sKey = StringReplace($sKey, $asComputer[0], "\", 1) If Not StringInStr($sKey, "\\") = 1 Then $sKey = StringTrimLeft($sKey, 1) EndIf EndIf If $asArray[0] = "" Then $asArray[0] = @ComputerName If StringInStr($sKey, "\\") = 1 And Not StringInStr($sKey, "\\\") = 1 Then Local $asUser = StringRegExp($sKey, "\\\\[^\\]*\\", 1) If Not @error Then $asArray[1] = StringTrimRight(StringTrimLeft($asUser[0], 2), 1) $sKey = StringReplace($sKey, $asUser[0], "", 1) EndIf EndIf If Not (StringInStr($sKey, "\") = 1 Or StringInStr($sKey, "\", 0, -1) = StringLen($sKey) Or StringInStr($sKey, "\\")) Then $asArray[2] = $sKey EndIf Return $asArray EndFunc ;==>Split_sKey 3+1 external executables are needed, look at notes at the top of che code. The _gollog udf is here. The abstract is this : it determines the current user SID it gives control to the admin user to the right registry entries, because they are changeable only by "system" account") it creates the needed pictures and write down to the registry the correct keys. Research on these topics was made in this thread.
-
Maybe is not this big life issue, but I want to change the Windows 10/11 current user account picture with a script. Not so simple but doable, I took ideas from: https://social.msdn.microsoft.com/Forums/sqlserver/en-US/3f50b25a-4c47-4bc8-959e-1108419288a7/how-to-set-specific-users-account-picture-from-cmd?forum=scripting So I assembled a testbed scritpt to prepare the avatar images in various sizes, and to modify the registry, finding the right user SID and right keys to modify. All seems to work, even regwrite instruction results OK (1), but no changes in the registry. So I found a showstopper problem: this registry key: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\AccountPicture\Users contains the definitions of the images for the various users (take a look at attached screenshoot). But I am not able to modify that key or subkeys and neither modify permissions also with an admin, because it seems only the good old "Administrator" (disabled by default in modern OSes) is able to change that permissions. I say this because I reactivated manually the Administrator, but in some environments (corporate domains) it is not so simple. Ideas ? I hate to automate the windows gui for a task like this 😒.
-
Hello So I thought it would be cool to use my Gravatar account to display my gravatar in a local GUI. I use this code: #cs ---------------------------------------------------------------------------- AutoIt Version: 3.3.14.2 Author: Skysnake Script Function: Example to download avatar from Gravatar and display locally #ce ---------------------------------------------------------------------------- ; Script Start ; includes #include <Crypt.au3> #include <InetConstants.au3> #include <MsgBoxConstants.au3> #include <WinAPIFiles.au3> #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #include <WinAPI.au3> ; declare Global vars Global $md5GraMail = '' ; will store email for Grvatar request request GravatarLogin() GetAvatar() Func GravatarLogin() ; get the email required for downloading the Gravatar Local $sGraMail = InputBox("Get Gravatar", "What is your email registered with Gravatar?", "someone@somewhere.com", "", -1, -1, 0, 0) ; from http://en.gravatar.com/site/implement/hash/ ; make the hash ; Local $dHash = _Crypt_HashData(GUICtrlRead($g_idInputEdit), $g_iAlgorithm) ; Create a hash of the text entered $md5GraMail = _Crypt_HashData(StringLower(StringStripWS($sGraMail, 8)), $CALG_MD5) ; lose the left two '0x' chars and convert to lower case $md5GraMail = StringLower(StringTrimLeft($md5GraMail, 2)) ; Display the result. MsgBox($MB_SYSTEMMODAL, "", $sGraMail & @CRLF & "md5 " & $md5GraMail, 15) EndFunc ;==>GravatarLogin ; example from Help file: /html/functions/InetGet.htm ; Download a file in the background. ; Wait for the download to complete. Func GetAvatar() ; Save the downloaded file to the temporary folder. Local $sFilePath = _WinAPI_GetTempFileName(@TempDir) ; from http://en.gravatar.com/site/implement/images/ ; <img src="https://www.gravatar.com/avatar/205e460b479e2e5b48aec07710c08d50" /> ; Download the file in the background with the selected option of 'force a reload from the remote site.' ; the next THREE options are alternatives ; Gravatar sample from here http://en.gravatar.com/site/implement/images/ ; 1 ;Local $hDownload = InetGet("https://www.gravatar.com/avatar/205e460b479e2e5b48aec07710c08d50", $sFilePath, $INET_FORCERELOAD, $INET_DOWNLOADBACKGROUND) ; the normal code, should show user avatar ; 2 Local $hDownload = InetGet("https://www.gravatar.com/avatar/" & $md5GraMail & "?d=retro", $sFilePath, $INET_FORCERELOAD, $INET_DOWNLOADBACKGROUND) ; my email hardcoded, downloads, but does not show avatar ; 3 ;Local $hDownload = InetGet("https://www.gravatar.com/avatar/cac637b47c9fecc8aa1dcdf71e7a4cc8", $sFilePath, $INET_FORCERELOAD, $INET_DOWNLOADBACKGROUND) ; Wait for the download to complete by monitoring when the 2nd index value of InetGetInfo returns True. Do Sleep(250) Until InetGetInfo($hDownload, $INET_DOWNLOADCOMPLETE) ; Retrieve the number of total bytes received and the filesize. Local $iBytesSize = InetGetInfo($hDownload, $INET_DOWNLOADREAD) Local $iFileSize = FileGetSize($sFilePath) ; Close the handle returned by InetGet. InetClose($hDownload) ; Display details about the total number of bytes read and the filesize. MsgBox($MB_SYSTEMMODAL, "", "The total download size: " & $iBytesSize & @CRLF & _ "The total filesize: " & $iFileSize, 1) Local $MyGravatar = @ScriptDir & "\Gravatar.jpg" FileCopy($sFilePath, $MyGravatar) MsgBox(0, "Now showing!", $MyGravatar, 5) ; make gui and show file GUICreate("My Gravatar in a GUI " & $MyGravatar, 350, 300, -1, -1, $WS_SIZEBOX + $WS_SYSMENU) ; will create a dialog box that when displayed is centered Local $idPic = GUICtrlCreatePic($MyGravatar, 50, 50, 80, 80) GUISetState(@SW_SHOW) ; Loop until the user exits. While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE ExitLoop EndSwitch WEnd ;FileDelete($MyGravatar) ; Delete the file. FileDelete($sFilePath) EndFunc ;==>GetAvatar Now, here is the issue. If I use the example from the Gravatar site, located here: http://en.gravatar.com/site/implement/images/ Then this code 205e460b479e2e5b48aec07710c08d50 downloads this pic (not me) AND it displays correctly. PROBLEM However, If I download my own Gravatar, I see the image in the @Script folder, BUT IT DOES NOT DISPLAY. The same with the retro image. To be clear, this image downloads, but is not displayed. I guess it has something to do with the format of my gravatar. Or that the display funtion GUICtrlCreatePic() does not like my gravatar. I would be grateful if someone would be willing to test this and may offer a suggestion or two... Skysnake