Solved

selecting attributes from AD

Posted on 2010-11-18
8
1,170 Views
Last Modified: 2012-08-14
I was able to modify this a bit but just wondering if someone could show me how to get certain attributes and how out of AD. For example if I wanted to get the lastlogon date, or the phone number, department, zip code. I know this might be trivial but not to me at least. Any help would be greatly appreciated. I know of course I would modify the LDAP line in order to point this to the OU or have it to start at the root.


$strFilter = "(objectCategory=User)"  
$objOU = New-Object System.DirectoryServices.DirectoryEntry("LDAP://DC=somedomain,DC=com")  
$objSearcher = New-Object System.DirectoryServices.DirectorySearcher
$objSearcher.SearchRoot = $objDomain
$objSearcher.SearchScope = "Subtree"
$objSearcher.PageSize = 1000
$objSearcher.Filter = $strFilter
 
$colProplist = "name"
foreach ($i in $colPropList){$objSearcher.PropertiesToLoad.Add($i)}

$colResults = $objSearcher.FindAll()
 
foreach ($objResult in $colResults)    
{$objItem = $objResult.Properties; $objItem.name}
0
Comment
Question by:tdodd72
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 4
  • 4
8 Comments
 
LVL 71

Assisted Solution

by:Chris Dent
Chris Dent earned 500 total points
ID: 34163457

It's not exactly trivial with that interface.
$Filter = "(&(objectClass=user)(objectCategory=person))"
$Properties = "name", "lastlogon", "telephonenumber", "department", "postalcode"

$Searcher = New-Object DirectoryServices.DirectorySearcher($Filter)
$Searcher.PageSize = 1000
$Searcher.PropertiesToLoad.AddRange($Properties)

$Searcher.FindAll() | Select-Object `
  @{n='Name';e={ $_.Properties["name"][0] }},
  @{n='LastLogon';e={ [DateTime]::FromFileTime($_.Properties["lastlogon"][0]) }},
  @{n='TelephoneNumber';e={ $_.Properties["telephonenumber"][0] }},
  @{n='Department';e={ $_.Properties["department"][0] }},
  @{n='ZipCode';e={ $_.Properties["postalcode"][0] }}

Open in new window

I dropped the following:

SearchRoot - Default value
SearchScope - Default value
Filter - Moved to the Constructor
PropertiesToLoad - Replaced with AddRange, neater

And I killed off the ForEach loop, this way is neater if you intend to drop the results to a file (can be done by adding " | Export-Csv somefile.csv" onto the end).

LastLogon also needs a note. Are you aware that this value is not replicated? If you have more than one DC the results you get here may be misleading.

HTH

Chris
0
 

Author Comment

by:tdodd72
ID: 34164614

So basically I can state the attribute in AD I am looking for and prepend this in front of this value below.

e={ $_.Properties["postalcode"][0] }}

How do you deal with the fact you have a bunch of DC’s in an environment. I have noticed that I get inaccurate logon times. Last question is what if I wanted to start doing this script in a child OU and not at the root. Can I just add the ADSI LDAP command back in.
0
 
LVL 71

Expert Comment

by:Chris Dent
ID: 34164655

> So basically I can state the attribute in AD I am looking for and prepend this in front of this value below.

Yep.

At the moment you must declare the attributes you want on the $Properties line. However, the Searcher returns almost everything by default so you may simply do away with $Properties and the PropertiesToLoad.AddRange line.

> How do you deal with the fact you have a bunch of DC’s in an environment

You can either query every DC, or you can pull lastLogonTimeStamp. lastLogonTimeStamp is replicated, but it may be up to 14 days out of date. How accurate do you need the times to be?

This version has the search root back in.
$SearchRoot = [ADSI]"LDAP://OU=somewhere,DC=domain,DC=com"
$Filter = "(&(objectClass=user)(objectCategory=person))"
$Properties = "name", "lastlogon", "telephonenumber", "department", "postalcode"

$Searcher = New-Object DirectoryServices.DirectorySearcher($SearchRoot, $Filter)
$Searcher.PageSize = 1000
$Searcher.PropertiesToLoad.AddRange($Properties)

$Searcher.FindAll() | Select-Object `
  @{n='Name';e={ $_.Properties["name"][0] }},
  @{n='LastLogon';e={ [DateTime]::FromFileTime($_.Properties["lastlogon"][0]) }},
  @{n='TelephoneNumber';e={ $_.Properties["telephonenumber"][0] }},
  @{n='Department';e={ $_.Properties["department"][0] }},
  @{n='ZipCode';e={ $_.Properties["postalcode"][0] }}

Open in new window

Note that we added the SearchRoot to the constructor (via New-Object) for the DirectorySearcher.

The search root will also be used to target specific DCs, like this:

$SearchRoot = [ADSI]"LDAP://server/OU=somewhere,DC=domain,DC=com"

And if you wanted a list of DCs you might just look at the Domain Controllers OU (in the script). Depending on your requirements for lastLogon accuracy :)

Chris
0
Does Powershell have you tied up in knots?

Managing Active Directory does not always have to be complicated.  If you are spending more time trying instead of doing, then it's time to look at something else. For nearly 20 years, AD admins around the world have used one tool for day-to-day AD management: Hyena. Discover why

 

Author Comment

by:tdodd72
ID: 34171813
So I tried to pull additional properties from an object and I am not getting anything. For example I tried to pull the created date of an object and received nothing.

$SearchRoot = [ADSI]"LDAP://DC=something,DC=com"
$Filter = "(&(objectClass=user)(objectCategory=person))"
$Properties = "name", "lastlogon", "telephonenumber", "department", "postalcode", "Created"



$Searcher = New-Object DirectoryServices.DirectorySearcher($SearchRoot, $Filter)
$Searcher.PageSize = 1000
$Searcher.PropertiesToLoad.AddRange($Properties)

$Searcher.FindAll() | Select-Object `
  @{n='Name';e={ $_.Properties["name"][0] }},
  @{n='LastLogon';e={ [DateTime]::FromFileTime($_.Properties["lastlogon"][0]) }},
  @{n='TelephoneNumber';e={ $_.Properties["telephonenumber"][0] }},
  @{n='Department';e={ $_.Properties["department"][0] }},
  @{n='ZipCode';e={ $_.Properties["postalcode"][0] }},
  @{n='Created';e={ $_.Properties["Created"][0] }}
0
 
LVL 71

Accepted Solution

by:
Chris Dent earned 500 total points
ID: 34171869
It's whenCreated rather than created. You also have to refer to property names in lower-case in the Select-Object part. So we get:
$SearchRoot = [ADSI]"LDAP://DC=something,DC=com"
$Filter = "(&(objectClass=user)(objectCategory=person))"
$Properties = "name", "lastlogon", "telephonenumber", "department", "postalcode", "whenCreated"

$Searcher = New-Object DirectoryServices.DirectorySearcher($SearchRoot, $Filter)
$Searcher.PageSize = 1000
$Searcher.PropertiesToLoad.AddRange($Properties)

$Searcher.FindAll() | Select-Object `
  @{n='Name';e={ $_.Properties["name"][0] }},
  @{n='LastLogon';e={ [DateTime]::FromFileTime($_.Properties["lastlogon"][0]) }},
  @{n='TelephoneNumber';e={ $_.Properties["telephonenumber"][0] }},
  @{n='Department';e={ $_.Properties["department"][0] }},
  @{n='ZipCode';e={ $_.Properties["postalcode"][0] }},
  @{n='Created';e={ $_.Properties["whencreated"][0] }}

Open in new window

Note that we can request the properties (PropertiesToLoad) regardless of case, its only when we want to extract them from $_.Properties that we have to care about case.

If you're unsure about the property names there are a number of ways you can see. For instance, you might use ADSIEdit.msc, or the Attribute Editor tab in AD Users and Computers (Win Vista / Win 7 / Win 2008 versions with View / Advanced), or you can get them with PowerShell:
(New-Object DirectoryServices.DirectorySearcher("(sAMAccountName=$Env:Username)")).FindOne().Properties

Open in new window

It won't be absolutely all of them, a few have to be explicitly requested (such as canonicalName).
HTH

Chris
0
 

Author Comment

by:tdodd72
ID: 34171943
Superb OUTSTANDING "(New-Object DirectoryServices.DirectorySearcher("(sAMAccountName=$Env:Username)")).FindOne().Properties" THIS IS what I have been looking for. Man I cannot believe all the properties I can pull with this thing. Thanks for your help again Mr. Powershell expert.
0
 

Author Closing Comment

by:tdodd72
ID: 34171956
Absolutely positively GREAT
0
 
LVL 71

Expert Comment

by:Chris Dent
ID: 34171966

You're welcome :)

Chris
0

Featured Post

Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

I thought I'd write this up for anyone who has a request to create an anonymous whistle-blower-type submission form created using SharePoint 2010 (this would probably work the same for 2013). It's not 100% fool-proof but it's as close as you can get…
A recent project that involved parsing Tableau Desktop and Server log files to extract reusable user queries for use in other systems. I chose to use PowerShell to gather the data, and SharePoint to present it...
Exchange organizations may use the Journaling Agent of the Transport Service to archive messages going through Exchange. However, if the Transport Service is integrated with some email content management application (such as an antispam), the admini…

749 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question