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}