locked
Save jpegs from Active Directory RRS feed

  • السؤال

  • Hi,

    I'm trying to create a VBS script that can run overnight and will output the image (if there is one) that is stored in the jpegPhoto attribute of Active Directory.

    I've used the script found here http://www.arricc.net/active-directory-photos-sharepoint.php to upload the initial set of pictures into AD, but now what I'd like to do is create a script that at set intervals can be run and will output the images into a folder in the format %USERNAME%.jpg, unfortunately my knowledge of scripting is limited, but I believe it needs to work something like this:

    Get all usernames
      For each username
        If jpegPhoto exists then
          Save jpegPhoto as username.jpg
        End If
      Next
    End

    Can anyone provide me with a starting point? I've chosen VBS as the other script was written in it, but I'm not overly fussed what language I write it in just so long as I can understand it :)

    Many thanks,
    CJ
    26/رجب/1430 11:40 م

الإجابات

  • Sorry for that. in PowerShell v1 we shouls first call the psbase member so add psbase infront of each propeties call:

    The following saves all users' jpegPhoto to the c:\UserADImaged directory

    $filter = '(&(objectCategory=Person)(objectClass=User))'
    $root= New-Object System.DirectoryServices.DirectoryEntry("LDAP://RootDSE")
    $searcher = New-Object System.DirectoryServices.DirectorySearcher $filter

    # filter only users from a certain OU
    #$searcher.searchroot = [adsi]'LDAP://OU=TEST,DC=domain,DC=com'

    $searcher.findall()  | foreach { 
     $user = [adsi]$_.path
     $sAMAccountName = $user.psbase.Properties["samaccountname"]
     $user.psbase.Properties["jpegPhoto"] | set-content "c:\UserADImaged\$sAMAccountName.jpg" -Encoding byte
    }


     


    Shay Levy [MVP]
    http://blogs.microsoft.co.il/blogs/ScriptFanatic
    PowerShell Toolbar
    • تم وضع علامة كإجابة بواسطة Chris_Moon_AU 28/رجب/1430 07:26 ص
    28/رجب/1430 07:14 ص
  • CJ,

    You will need to start a new thread with this question please, the original question was asked and mark answered 3 months ago. You may want to post a link to the original thread as Shay and the other moderators answers many many questions and it would be helpful to them to see what script you are referring to in your post.


    Thank you for posting and have a great day.
    • تم وضع علامة كإجابة بواسطة IamMred 01/ذو القعدة/1430 05:57 م
    01/ذو القعدة/1430 05:57 م

جميع الردود

  • Here's a powershell version:

    # read an image and store it in a byte array
    [byte[]]$jpg = Get-Content c:\shay.jpg -encoding byte

    # bind to the user object with adsi
    $user = [adsi]"LDAP://cn=shay,cn=users,dc=homelab,dc=loc"

    # clear previous image if exist
    $user.Properties["jpegPhoto"].Clear()

    # write the image to the user's jpegPhoto attribute
    $null = $user.Properties["jpegPhoto"].Add($jpg)
    $user.CommitChanges()

    #Write it back to a file with diffrent name so you can check its valid
    $user = [adsi]"LDAP://cn=shay,cn=users,dc=homelab,dc=loc"
    $user.Properties["jpegPhoto"] | set-content c:\shay1.jpg -Encoding byte

    HTH


    Shay Levy [MVP]
    http://blogs.microsoft.co.il/blogs/ScriptFanatic
    PowerShell Toolbar
    27/رجب/1430 04:38 م
  • Thanks for the quick reply Shay, I'm glad you've got a script in powershell as I've been meaning to start using it for a while, this should get me on my way!

    Unfortunately when I execute:
    $user.Properties["jpegPhoto"] | set-content c:\shay1.jpg -Encoding byte

    I recieve the following error:
    Unable to index into an object of type System.Management.Automation.PSMethod


    I've also found the below script here (http://www.vistax64.com/powershell/75306-active-directory-getting-list-users.html)

    $Searcher=New-Object System.DirectoryServices.DirectorySearcher
    $Searcher.Filter="(objectcategory=user)"
    $Searcher.PageSize = 1000
    $Results=$Searcher.FindAll()

    So in your script can I change the line $user = [adsi]$results.path?

    And finally, where you have
    set-content C:\shay1.jpg -encoding byte,

    Can I change that to:
    set-content C:\$user.properties["sAMAccountName"].jpg -encoding byte

    Thanks for you help,
    CJ
    28/رجب/1430 05:51 ص
  • Sorry for that. in PowerShell v1 we shouls first call the psbase member so add psbase infront of each propeties call:

    The following saves all users' jpegPhoto to the c:\UserADImaged directory

    $filter = '(&(objectCategory=Person)(objectClass=User))'
    $root= New-Object System.DirectoryServices.DirectoryEntry("LDAP://RootDSE")
    $searcher = New-Object System.DirectoryServices.DirectorySearcher $filter

    # filter only users from a certain OU
    #$searcher.searchroot = [adsi]'LDAP://OU=TEST,DC=domain,DC=com'

    $searcher.findall()  | foreach { 
     $user = [adsi]$_.path
     $sAMAccountName = $user.psbase.Properties["samaccountname"]
     $user.psbase.Properties["jpegPhoto"] | set-content "c:\UserADImaged\$sAMAccountName.jpg" -Encoding byte
    }


     


    Shay Levy [MVP]
    http://blogs.microsoft.co.il/blogs/ScriptFanatic
    PowerShell Toolbar
    • تم وضع علامة كإجابة بواسطة Chris_Moon_AU 28/رجب/1430 07:26 ص
    28/رجب/1430 07:14 ص
  • Thanks Shay that's brilliant, it does just what I need and has taught me something about PowerShell!
    28/رجب/1430 07:27 ص
  • Hi Shay,

    I'm attempting to modify the script you provided to copy phone numbers from the telephoneNumber attribute to ipPhone, here's the script I've modified which runs without any errors, however it doesn't appear to actually update the ipPhone attribute:

    $filter = '(&(objectCategory=Person)(objectClass=User))'
    $root= New-Object System.DirectoryServices.DirectoryEntry("LDAP://RootDSE")
    $searcher = New-Object System.DirectoryServices.DirectorySearcher $filter

    # filter only users from a certain OU
    #$searcher.searchroot = [adsi]'LDAP://OU=TEST,DC=domain,DC=com'

    $searcher.findall()  | foreach {
     $user = [adsi]$_.path
     IF ($user.psbase.Properties["telephoneNumber"] -ne $NULL)
     {
     $user.psbase.Properties["ipPhone"] | set-content $user.psbase.Properties["telephoneNumber"]}
    }

    Any suggestions what's up would be great!

    Cheers
    CJ

    26/شوال/1430 12:33 ص
  • CJ,

    You will need to start a new thread with this question please, the original question was asked and mark answered 3 months ago. You may want to post a link to the original thread as Shay and the other moderators answers many many questions and it would be helpful to them to see what script you are referring to in your post.


    Thank you for posting and have a great day.
    • تم وضع علامة كإجابة بواسطة IamMred 01/ذو القعدة/1430 05:57 م
    01/ذو القعدة/1430 05:57 م
  • Hi Shay,

    Thanks for the Script. I am able to saves photo from the AD.

    Our AD have approx 20 k Users and we have uploaded around 3000 Photos.

    When i am running the script it saves only 69 photos.. can you please tel us the reson for the same or there is any limit of the script

    23/ربيع الأول/1433 12:15 م
  • I can't think of a reason for the script to stop after 69 users. How many objects do you get with this:

    $filter = '(&(objectCategory=Person)(objectClass=User))'
    $root= New-Object System.DirectoryServices.DirectoryEntry("LDAP://RootDSE")
    $searcher = New-Object System.DirectoryServices.DirectorySearcher $filter
    $searcher.FindAll() | Measure-Object


    Shay Levy [MVP]
    PowerShay.com
    PowerShell Toolbar

    23/ربيع الأول/1433 12:35 م
  • We've got about 800 users and 400 photos and the script runs through all 400 without issue, so I can't think why yours would stop at 69!

    Cheers

    23/ربيع الأول/1433 12:40 م
  • It is showing Count = 1500

    We did small change in Script

    $filter = '(&(objectCategory=Person)(objectClass=User))'
    $root= New-Object System.DirectoryServices.DirectoryEntry("LDAP://RootDSE")
    $searcher = New-Object System.DirectoryServices.DirectorySearcher $filter

    # filter only users from a certain OU
    #$searcher.searchroot = [adsi]'LDAP://OU=TEST,DC=domain,DC=com'

    $searcher.findall()  | foreach {
     $user = [adsi]$_.path
     $sAMAccountName = $user.psbase.Properties["samaccountname"]
     $user.psbase.Properties["thumbnailphoto"] | set-content "d:\UserADImaged\$sAMAccountName.jpg" -Encoding byte

    We used Thumbnailphoto instead of jpegphoto

     

    23/ربيع الأول/1433 06:54 م
  • And you're sure that all 1500 users have a picture stored in the thumbnailphoto attribute?

    Shay Levy [MVP]
    PowerShay.com
    PowerShell Toolbar

    24/ربيع الأول/1433 03:47 م
  • Do it this way  so you will get all objects and not just the first 1500.

    $searcher = [adsisearcher] '(&(objectCategory=Person)(objectClass=User))' 
    $searcher.PageSize=500
    $searcher.findall()  | measure-object 
    }

    Also use the type acelerators here as it makes the code cleaner.

    For the current domain you do not need to set teh root or address the domain.  ADSI clases default all of these values.  Just set the ones you want to cjamge.  In this case you need the filter and the paging value

    The above should return a count of more than 3000.


    ¯\_(ツ)_/¯

    24/ربيع الأول/1433 07:36 م
  • Here is the full code

    $searcher = [adsisearcher] '(&(objectCategory=Person)(objectClass=User))' 
    $searcher.SizeLimit=500
    $searcher.findall()  | foreach { 
          $user=$_.GetDirectoryEntry()
          # the following line may throw errors if there is no photo.
          $user.psbase.Properties["thumbnailphoto"] | set-content "d:\UserADImaged\$sAMAccountName.jpg" -Encoding byte
    }


    ¯\_(ツ)_/¯

    24/ربيع الأول/1433 07:39 م