Null valued expression

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 $
$UserLockedOut | Add-Member -type NoteProperty -Name LastLogon -value $.LastLogonDate
$AddlUserInfo=Get-ADUser $
$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 $
$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.

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

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;}

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)

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

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.