Most Azure AD tenants are synchronized from an on-premises Active Directory environment. The AADC server synchronizes accounts from different organizational units (OUs), different domains – possibly even from different forests. However, you lose all hierarchical information up there – Azure AD stores all accounts in the same flat structure. So, wouldn’t it be nice to know where the original AD object came from?
Actually, it’s possible, and it’s not even particularly difficult to figure out: There is the onPremisesDistinguishedName property of each Azure AD user. Microsoft introduced this property with the AADC version 1.1.553.0 (June 2017). This is just the distinguished name of the original AD account. A distinguished name is the LDAP Pathname of this object and it specifies exactly the domain and the OU where the object comes from. This information is somewhat hidden in the extension data of the Azure AD object, but it is not hard to read. Let’s have a look at a normal Get-AzureADUser output:
The ‘ExtensionProperty’ can be evaluated very easily, you do not have to use the Get-AzureADUserExtension cmdlet! Just go for the child properties of the ExtensionProperty:
(Get-AzureADUser -Searchstring "Chris Crimson").ExtensionProperty.onPremisesDistinguishedName
If you want to have a overview list of the on premises LDAP paths, you could do something like this:
Get-AzureADUser | % {
$_ | Add-Member -MemberType NoteProperty -Name OnPremisesDistinguishedName -Value $_.ExtensionProperty.onPremisesDistinguishedName
$_
} | Select DisplayName,UserPrincipalName,OnPremisesDistinguishedName | Out-GridView
This adds the onPremisesDistinguishedName to the direct normal property members of each user object. By adding a PSObject node property. You can treat it like any other attribute on the users. The result is a handy gridview where you can filter and sort the acounts:
That was the duty, now the freestyle
You may have noticed that LDAP distinguished names are not very useful for sorting. But what if we actually want to sort according to the LDAP hierarchy? Easy – and yet not that easy. We have to convert the onPremisesDistinguishedName value to a so-called canonical name – this is a notation of the LDAP path where the top-level hierarchy is written first: The reverse order compared to what we got in the distinguished name. It’s a game of splitting strings, reverse array orders, replace characters… But you can do it with a compact coded function and add the resulting canonical name again as a PSObject node property:
Function Get-CanonicalName ($dn) {
if ($dn) {
#Split the dn string up into parts, ignore the escaped commas (\,)
$d = $dn.Replace('\,', '~~').Split(',')
#Get parts excluding the FQDN parts, trim off the RDN specifier and reverse the order
$arr = (@(($d | ? { $_ -notmatch 'dc=' }) | % { $_.Substring(3).Replace('~~',',') }))
[array]::Reverse($arr)
#Build the canonical name: first the FQDN, second the hierarchical path
"{0}/{1}" -f (($d | ? { $_ -match 'dc=' } | % { $_.Replace('DC=','')}) -join '.'), ($arr -join '/')
} else {
""
}
}
Get-AzureADUser | % {
$_ | Add-Member -MemberType NoteProperty -Name OnPremisesCanonicalName -Value (Get-CanonicalName $_.ExtensionProperty.onPremisesDistinguishedName)
$_
} | select DisplayName,UserPrincipalName,OnPremisesCanonicalName | Out-GridView
The Result:
One thought on “Where do you come from ? … The onPremisesDistinguishedName Property”
Great article, thanks a lot Philipp.
You can also get the full list of extension attributes thanks to the cmdlet “Get-AzureADUserExtension”. It can be useful when you have to focus on one specific user.
PS C:\WINDOWS\system32> Get-AzureADUserExtension -ObjectId ‘charles.farrell@kuyb.onmicrosoft.com’
Key Value
— —-
odata.metadata https://graph.windows.net/46e433fc-ddcd-4779-935…
odata.type Microsoft.DirectoryServices.User
createdDateTime 4/9/2019 4:12:06 PM
employeeId
onPremisesDistinguishedName CN=Charles FARRELL,OU=USA,OU=Jet,OU=Cloud,DC=SFB,DC=lab
userIdentities []
Source: https://docs.microsoft.com/en-us/powershell/module/azuread/get-azureaduserextension?view=azureadps-2.0