Home > Enterprise >  Powershell Expression gives no results
Powershell Expression gives no results

Time:11-17

I have created an expression that should return the OU canonical name. A small outline:

@(Search-ADAccount -LockedOut -UsersOnly) | Select-Object Name,SamAccountName,@{Name="OU";Expression={((Get-ADOrganizationalUnit -Identity $($_."DistinguishedName")).CanonicalName)}}

However, this expression returns an empty OU column, the other 2 columns are filled.

My question is what is wrong with this expression? Any feedback is appreciated.

With kind regards, TheStingPilot

CodePudding user response:

A troubleshooting technique for calculated properties:

The script block stored in the Expression entry of a hashtable defining a calculated property:

  • runs in a child scope relative to the caller's scope.

  • more importantly, it quietly ignores any errors that occur.

However, such errors are recorded in the automatic $Error variable, so to diagnose your problem you can do the following:

$Error.Clear()

Search-ADAccount -LockedOut -UsersOnly | 
  Select-Object Name, SamAccountName, @{Name="OU";Expression={(Get-ADOrganizationalUnit -Identity $_.DistinguishedName).CanonicalName}}

$Error # Output the errors that occurred inside the calculated property's script block.

Solution to your specific problem:

As Santiago Squarzon's helpful answer explains, you need to extract the OU's distinguished name (DN) from the user's and pass the former to Get-ADOrganizationalUnit -Identity.

While $_.DistinguishedName.Split(',',2)[1], which removes the first ,-separated token from the user's DN will typically work, it can fail with DNs that use escaped , chars. (\,) that are to be treated as part of a value; e.g.:

# !! Simple splitting by the first "," is NOT enough here:
PS> 'CN=Martin Luther King\, Jr.,OU=Ministry,DC=example,DC=org'.Split(',',2)[1]

 Jr.,OU=Ministry,DC=example,DC=org # !! WRONG

To also handle these edge cases, i.e. to robustly extract the OU's DN from a user's, a sophisticated regex is required, in combination with the -replace operator:

# OK: The regex correctly recognizes the escaped \, as such.
PS> 'CN=Martin Luther King\, Jr.,OU=Ministry,DC=example,DC=org' -replace '^. ?((?<=[^\\])(?:\\\\)*),'

OU=Ministry,DC=example,DC=org  # OK

To put it all together:

Search-ADAccount -LockedOut -UsersOnly | 
  Select-Object Name, 
                SamAccountName, 
                @{
                  Name = 'OU'
                  Expression = {
                    (Get-ADOrganizationalUnit -Identity ($_.DistinguishedName -replace '^. ?((?<=[^\\])(?:\\\\)*),')).CanonicalName
                  }
                }

CodePudding user response:

The issue with your code is that you're trying to feed Get-ADOrganizationalUnit a user's DistinguishedName instead of an OU's DistinguishedName which is not valid.

It's also worth mentioning, you're missing -Properties CanonicalName on Get-ADOrganizationalUnit.

Try this instead:

$e={(Get-ADOrganizationalUnit -Identity $_.DistinguishedName.Split(',',2)[1] -Properties CanonicalName).CanonicalName}
Search-ADAccount -LockedOut -UsersOnly |
Select-Object Name, SamAccountName, @{Name="OU";Expression=$e}
  • Related