Author Posts

April 9, 2014 at 7:47 am

Using a combination of Search-ADAccount, Get-ADAccount and the directory class ADSISearcher object, I am trying to compile a list of properties into a PSObject. Some of the cmdlets do not yield properties I need so I am combining the information from what I can get from each one. I am trying to gather information on users who have been locked out of our domain.

The script is below:

Function Get-UserInfo {
Begin {}
Process {
$UserLockedOut=new-object psobject
$UserLockedOut | Add-Member -type noteproperty -name UserName -value $_.Name
$UserLockedOut | Add-Member -type NoteProperty -Name DN -value $_.DistinguishedName
$UserLockedOut | Add-Member -type NoteProperty -Name LastLogon -value $_.LastLogonDate
$AddlUserInfo=Get-ADUser $_.Name
$UserLockedOut | Add-Member -type noteproperty -name LastName -value $AddlUserInfo.Surname
$UserLockedOut | Add-Member -type noteproperty -name FirstName -value $AddlUserInfo.GivenName
#$User=Get-ADObject -LDAPFilter "(&(objectClass=User)(objectCategory=person)(sAMAccountName=$_.Name))"
#$User=Get-ADObject -Identity $_.DistinguishedName
$User=$searcher.FindOne()|select -ExpandProperty Properties
$UserLockedOut | Add-Member -type noteproperty -name Telephone -value $tele
$UserLockedOut | Add-Member -type noteproperty -name Office -value $office
Write-Output $UserLockedOut
End {}
} #end function Get-UserInfo
$Locked=Search-ADAccount -LockedOut -ResultPageSize 500 -UsersOnly

I keep getting a null valued expression warning at the $tele and $office lines. It seems that $searcher.FindOne() is not finding anything. I have identical code in another script and it pulls up the information just fine. Any hints on what I am missing would be appreciated.

April 9, 2014 at 8:46 am

You've piped the result of $searcher.FindOne() to "Select -ExpandProperty Properties", but then tried to access $User.Properties.Item() on the next line. $User.Item() would probably work, assuming that FindOne() returned an object.

In any case, that seems like wasted effort. You're already calling Get-ADUser, so you could just grab all the properties you need from there. Something like this:

$selectProperties = @(
    @{ Name = 'Name';      Expression = { $_.SamAccountName } }
    @{ Name = 'DN';        Expression = { $_.DistinguishedName } }
    @{ Name = 'LastLogon'; Expression = { $_.LastLogonDate } }
    @{ Name = 'FirstName'; Expression = { $_.GivenName } }
    @{ Name = 'LastName';  Expression = { $_.Surname } }
    @{ Name = 'Telephone'; Expression = { $_.OfficePhone } }
    @{ Name = 'Office';    Expression = { $_.physicalDeliveryOfficeName } }

Search-ADAccount -LockedOut -ResultPageSize 500 -UsersOnly |
Get-ADUser -Properties LastLogonDate, OfficePhone, physicalDeliveryOfficeName |
Select-Object -Property $selectProperties

April 9, 2014 at 10:16 am

I originally had the expression to $User.Item(). I just revised it back and I get the same result. I will try your script but Get-ADUser does not seem to have the telephone or physicaloffice properties. Here is the output of the command get-aduser -Identity "DistiguishedNameof User"|GM. No telephone or office.

TypeName: Microsoft.ActiveDirectory.Management.ADUser

Name MemberType Definition
—- ———- ———-
Contains Method bool Contains(string propertyName)
Equals Method bool Equals(System.Object obj)
GetEnumerator Method System.Collections.IDictionaryEnumerator ...
GetHashCode Method int GetHashCode()
GetType Method type GetType()
ToString Method string ToString()
Item ParameterizedProperty Microsoft.ActiveDirectory.Management.ADPr...
DistinguishedName Property System.String DistinguishedName {get;set;}
Enabled Property System.Boolean Enabled {get;set;}
GivenName Property System.String GivenName {get;set;}
Name Property System.String Name {get;}
ObjectClass Property System.String ObjectClass {get;set;}
ObjectGUID Property System.Nullable`1[[System.Guid, mscorlib,...
SamAccountName Property System.String SamAccountName {get;set;}
SID Property System.Security.Principal.SecurityIdentif...
Surname Property System.String Surname {get;set;}
UserPrincipalName Property System.String UserPrincipalName {get;set;}

April 9, 2014 at 10:18 am

That's what the -Properties parameter is for, in case you want to retrieve more properties than the ones that it gives you by default. Notice in my example, I called it like this:

Get-ADUser -Properties LastLogonDate, OfficePhone, physicalDeliveryOfficeName

OfficePhone is another name for telephoneNumber, when using the AD cmdlets. It translates some of the LDAP display names to something more user-friendly. (LastLogonDate is lastLogonTimestamp in LDAP, for example)

April 9, 2014 at 10:39 am

Nice script btw. Yours works. I can go with that. Still troubled over why mine didn't. Thank you, Dave.

April 9, 2014 at 10:42 am

Now that I look at your original script a little closer, I see that you had a similar problem. DirectorySearcher only returns a few properties, by default. If you want more, you need to add them to the $searcher.PropertiesToLoad collection. Alternatively, you could just bind straight to the user object and have access to everything, by doing something like this:

$user = [adsi]"LDAP://$($_.DistinguishedName)"

# etc

You'll find that in many cases, properties accessed via the System.DirectoryServices classes are actually collections, even if the property appears to be single-valued. Sometimes you have to throw in some [0] indexes into your code.