Null valued expression

This topic contains 5 replies, has 2 voices, and was last updated by  Dave Wyatt 3 years, 7 months ago.

  • Author
    Posts
  • #14402

    rambog cnonline.net
    Participant

    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
    $searcher=[ADSISearcher]"(&(objectClass=User)(objectCategory=person)(sAMAccountName=$UserLockedOut.UserName))"
    $User=$searcher.FindOne()|select -ExpandProperty Properties
    $tele=$User.Propterties.Item("telephonenumber")
    $office=$User.Properties.Item("physicaldeliveryofficename")
    $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
    $Locked|Get-UserInfo

    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.

  • #14406

    Dave Wyatt
    Moderator

    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
    
  • #14408

    rambog cnonline.net
    Participant

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

  • #14409

    Dave Wyatt
    Moderator

    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)

  • #14410

    rambog cnonline.net
    Participant

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

  • #14411

    Dave Wyatt
    Moderator

    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)"
    $user.telephoneNumber
    $user.physicalDeliveryOfficeName
    
    # 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.

You must be logged in to reply to this topic.