List AD group members when the group contains foreign security principals

Written by Luke Arntz on
Filed under Code
Tagged as Windows PowerShell

Article Contents


List AD Group Members

Getting an active directory group’s member list is as simple as Get-ADGroupMember if the group only has members from the current domain. However, if you need to get group members for a group that has foreign security principals (users from another domain) things get a bit more complicated. Even more so when some of those objects have been orphaned.

If you’re lucky you’ll end up with a user list that contains SID’s from another domain mixed with users from the local domain. At other times, you may get an unspecified error.

1
2
3
4
5
6
7
PS C:\Users\administrator> Get-ADGroupMember example_group
Get-ADGroupMember : An unspecified error has occurred
At line:1 char:1
+ Get-ADGroupMember example_group
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (retail_merch_prod:ADGroup) [Get-ADGroupMember], ADException
    + FullyQualifiedErrorId : ActiveDirectoryServer:0,Microsoft.ActiveDirectory.Management.Commands.GetADGroupMember

Translating Foreign Security Principals

To get actual user names from the SID’s well need to use the translate() function from the .NET [System.Security.Principal.SecurityIdentifier] type.

Function to List Users

Here the function I use to get members of groups with foreign security principals.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
function Get-AdGroupForeignMembers
{
    param(
        [string]$group
    )

    $translatedMembers = @()

    $members = (Get-ADGroup $group -Properties member).member
    foreach($m in $members)
    {
        $orphan = $false
        $name = ""
        $dn = $([adsi]$("LDAP://$m")).DistinguishedName
        $ado = Get-ADObject -Identity $($dn)
        if($ado.Name -match "^S-\d-\d-\d\d")
        {
            
            try 
            {
                $name =  ([System.Security.Principal.SecurityIdentifier] $ado.Name).Translate([System.Security.Principal.NTAccount])
            }
            catch 
            {
                $name = $ado.Name
                $orphan = $true
            }

        }
        else 
        {
                $name = $ado.Name
        }

        $translatedMembers += [PSCustomObject] @{
            Name = $name
            Orphaned = $orphan
        }
    }

    Write-Output $translatedMembers
}

References

Related Articles

Top