I'm a DBA tasked with querying info from AD for a security audit. I need to create a Report that can put all AD objects into a CSV and resolve the Foreign Security Principals from another domain. I do have a trust between the domains. I have following script working in powershell coming from: http://social.technet.microsoft.com/Forums/scriptcenter/en-US/59d99252-2b1c-490e-818c-d1a645332293/powershell-ad-group-membership?forum=ITCG&prof=required
$D = [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain()
$Domain = [ADSI]"LDAP://$D"
$Searcher = New-Object System.DirectoryServices.DirectorySearcher
$Searcher.PageSize = 200
$Searcher.SearchScope = "subtree"
$Searcher.SearchRoot = "LDAP://" + $Domain.distinguishedName
# Specify attributes to retrieve.
$Searcher.PropertiesToLoad.Add("distinguishedName") > $Null
$Searcher.PropertiesToLoad.Add("sAMAccountName") > $Null
# Hash table.
$MemberList = @{}
# Retrieve all users, groups, and computers.
$Searcher.Filter = "(|(objectCategory=user)(objectCategory=group)(objectCategory=computer))"
$Results = $Searcher.FindAll()
ForEach ($Result In $Results)
{
$DN = $Result.Properties.Item("distinguishedName")
$Name = $Result.Properties.Item("sAMAccountName")
$MemberList.Add($($DN), $($Name))
}
# Filter on all groups.
$Searcher.Filter = "(objectCategory=group)"
$Searcher.PropertiesToLoad.Add("member") > $Null
$Results = $Searcher.FindAll()
ForEach ($Result In $Results)
{
$Name = $Result.Properties.Item("sAMAccountName")
$Line = """DN,$Name"""
$Members = $Result.Properties.Item("member")
ForEach ($Member In $Members)
{
If ($MemberList.ContainsKey($Member))
{
# Substitute the sAMAccountName from hash table.
$Line = $Line + ",""" + $MemberList[$Member] + """"
}
Else
{
# Use the Distinguished Name.
$Line = $Line + ",""" + $Member + """"
}
}
$Line
}
Then I found an script coming from http://activelydirect.blogspot.com/2011/01/dealing-with-foreignsecurityprincipal.html#comment-form , My hope is I could add the following to the first script and get them to resolve. But any input is welcome.
$securityPrincipalObject = New-Object System.Security.Principal.SecurityIdentifier($object.cn)
($domain, $sAMAccountName) = ($securityPrincipalObject.Translate([System.Security.Principal.NTAccount]).value).Split("\")
If your question is will the second script work for translating a Foreign Security Principle from a trusted domain into a username, then yes, I have used similar code to do so with good results. Just be sure that what you pass to the System.Security.Principal.SecurityIdentifier constructor is only the SID of the FSP (e.g. "S-1-5-21-...") and not the distinguishedName or "CN=S-1-5-21-...".
UPDATE:
if ($dN.StartsWith("CN=S-"))
{
$SIDText = ($dN.Split(","))[0].SubString(3)
$SID = New-Object System.Security.Principal.SecurityIdentifier $SIDText
Write-Output $SID.Translate([System.Security.Principal.NTAccount]).Value
}
else
{
Write-Output $dN
}