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
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:
$exp = { ($_.DistinguishedName.Split(',', 2)[1] | Get-ADOrganizationalUnit -Properties CanonicalName).CanonicalName }
Search-ADAccount -LockedOut -UsersOnly |
Select-Object Name, SamAccountName, @{ N = "OU"; E = $exp }
Now, this syntax using calculated properties with Select-Object
above is really hard to read but also very inefficient, it is querying the OUs per every user and there is a very high chance that the same OU will be queried more than once. What I would recommend instead is to cache the OUs in a hashtable with key = the OU DN
and value = the OU CanonicalName
.
This is much better:
$cache = @{}
Search-ADAccount -LockedOut -UsersOnly | ForEach-Object {
$ouDN = $_.DistinguishedName.Split(',', 2)[1]
if (-not $cache.ContainsKey($ouDN)) {
$ou = $ouDN | Get-ADOrganizationalUnit -Properties CanonicalName
$cache[$ouDN] = $ou.CanonicalName
}
[PSCustomObject]@{
Name = $_.Name
SamAccountName = $_.SamAccountName
OU = $cache[$ouDN]
}
}