Search code examples
powershellactive-directoryexpression

Nested Expression in Powershell returning part of Expression


Trying to pull some information from AD through Powershell, Specifically: samaccountname First Name Last Name Last Logon Date Password Last Set Enabled Password Policy applied

The way that I am proving password policy applied is with Get-ADUserResultantPasswordPolicy, and using the appliesto attribute to show where the user is getting their policy, since we are using fine grain password policies.

get-adgroupmember  <Group> -Recursive | %  {get-aduser $_ -properties *}| select samaccountname,givenname,surname,lastlogondate,@{Name='PwdLastSet';Expression={[DateTime]::FromFileTime($_.PwdLastSet)}},enabled,@{name="MemberOf"; Expression={  $(Get-ADUserResultantPasswordPolicy $_) | select  (@{Expression={ ($_.AppliesTo|%{$_.split(',')[0].substring(3)}) }})}} | OGV 

This command actually pulls all of the requested information

samaccountname givenname  surname lastlogondate        PwdLastSet            enabled MemberOf                                        
-------------- ---------  ------- -------------        ----------            ------- --------                                        
<Account>          <First>     <Last>               <Date> <Date> True       @{ ($_.AppliesTo|%{$_.split(',')[0].substring(3)}) =<Applies to Group>}          

I am trying to figure out why it's adding that extra bit '@{ ($.AppliesTo|%{$.split(',')[0].substring(3)}) =' before showing the resultantpolicy.appliesto.


Solution

  • This is expected behavior - if you fail to supply a name or label alongside a calculated expression, Select-Object will use the expression's own source code extent as the resulting property name:

    PS ~> 1 |Select { $_ * 10 }
    
     $_ * 10
    ---------
           10
    
    PS ~> Get-Process -Id $PID |Select @{Expression={$_.Name}}
    
    $_.Name
    -------
    pwsh
    
    

    Skip the nested Select pipeline and instead use ForEach-Object (alias %) to calculate the property value(s) directly:

       ... |Select-Object ...,@Name="MemberOf"; Expression={$(Get-ADUserResultantPasswordPolicy $_).AppliesTo |% { $_.Split(',')[0].Substring(3)}}}