ADGroupMemberObjects.psm1

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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
function Get-ADGroupMemberObjects {
    [CmdletBinding(ConfirmImpact = 'Low')]
    param(
        [parameter(Mandatory = $true)][ValidateNotNullOrEmpty()]
        [string]$GroupNTAccount
    )

    $GroupDomain = $GroupNTAccount.Split("\") | Select-Object -First 1
    $GroupName = $GroupNTAccount.Split("\") | Select-Object -Last 1
    $GroupDomainController = (Get-ADDomainController -Discover -Domain $GroupDomain -ErrorAction SilentlyContinue).HostName | Select-Object -First 1

    if (!$GroupDomainController) {
        throw "Domain Controller Discovering Error in [$($GroupDomain)]."
    }

    try {
        $GroupDN = Get-ADGroup -Server $GroupDomainController $GroupName -ErrorAction SilentlyContinue | Select-Object -ExpandProperty distinguishedName
    }
    catch {
        throw "Group [$($GroupName)] is not found in [$($GroupDomain)]."
    }
    
    $ADGroupMemberObjects = (Get-ADObject -Server $GroupDomainController $GroupDN -Properties member).member  
    $ADGroupMemberObjectsResult = @()

    ForEach ($ADGroupMemberObject in $ADGroupMemberObjects) {

        $ADGroupMemberObjectDomain = ($ADGroupMemberObject.Substring($ADGroupMemberObject.IndexOf("DC=")) -Split "," | ? { $_ -like "DC=*" }) -join "." -replace ("DC=", "")

        try {
            $ADGroupMemberObjectDomainController = (Get-ADDomainController -Discover -Domain $ADGroupMemberObjectDomain -ErrorAction SilentlyContinue).HostName | Select-Object -First 1
            $ADGroupMemberObject = Get-ADObject -Server $ADGroupMemberObjectDomainController $ADGroupMemberObject -Properties ObjectClass, objectSid | Where-Object -Property ObjectClass -in ("user", "foreignSecurityPrincipal", "group")
        }
        catch {
            continue
        }

        try {
            $NTAccount = (New-Object Security.Principal.SecurityIdentifier $ADGroupMemberObject.objectSid).translate( [Security.Principal.NTAccount] ).ToString()
        }
        catch {
            continue
        }

        if ($ADGroupMemberObject.ObjectClass -eq "group") {
            $ADGroupMemberObjectsResult += Get-ADGroupMemberObjects -GroupNTAccount $NTAccount
            continue
        }

        $Domain = $NTAccount.Split("\") | Select-Object -First 1
        $DomainController = (Get-ADDomainController -Discover -Domain $Domain -ErrorAction SilentlyContinue).HostName | Select-Object -First 1
        if ($DomainController) {
            try {
                $ADObjectUser = Get-ADUser -Server $DomainController $ADGroupMemberObject.objectSid -Properties DisplayName, Department, Manager
            }
            catch {
                $ADObjectUser = $null
            }

            if ($ADObjectUser) {
                try {
                    $ADObjectManager = Get-ADUser -Server $DomainController $ADObjectUser.Manager -Properties DisplayName
                }
                catch {
                    $ADObjectManager = $null
                }
                $ADGroupMemberObjectsResult += New-Object -TypeName PSObject -Property @{
                    NTAccount   = $NTAccount
                    DisplayName = $ADObjectUser.DisplayName
                    Department  = $ADObjectUser.Department
                    Manager     = $ADObjectManager.DisplayName
                }
            }
        }
    }

    return $ADGroupMemberObjectsResult | Select-object -Property NTAccount, DisplayName, Department, Manager -Unique
}

function Export-ADGroupMemberObjects {
    [CmdletBinding(ConfirmImpact = 'Low')]
    param(
        [parameter(Mandatory = $true)][ValidateNotNullOrEmpty()]
        [string]$GroupNTAccount,
        [parameter(Mandatory = $true)][ValidateNotNullOrEmpty()]
        [string]$FileName
    )
    
    $ADGroupMemberObjects = Get-ADGroupMemberObjects -GroupNTAccount $GroupNTAccount
    $ADGroupMemberObjects | Export-Csv $FileName -NoTypeInformation -Encoding "UTF8"
    $ADGroupMemberObjects
}

$GroupNTAccountArgumentCompleter = {
    param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters)
    
    $wordToComplete = $wordToComplete.Replace("'", "")
    
    if ($wordToComplete -Match "\\") {
        $GroupDomain = $wordToComplete.Split("\").ToUpper() | Select-Object -First 1
    }
    else {
        $GroupDomain = (Get-ADDomain).NetBIOSName
    }
    
    $GroupName = $wordToComplete.Split("\") | Select-Object -Last 1
    $GroupDomainController = (Get-ADDomainController -Discover -Domain $GroupDomain).HostName | Select-Object -First 1
    $groups = Get-ADGroup -Server $GroupDomainController -Filter "Name -like '$GroupName*'"
    $groups | ForEach-Object {
        New-Object -Type System.Management.Automation.CompletionResult -ArgumentList "'$GroupDomain\$($_.Name)'",
        $_.Name,
        "ParameterValue",
        $_.Name
    }
}

Register-ArgumentCompleter -CommandName Get-ADGroupMemberObjects -ParameterName GroupNTAccount -ScriptBlock $GroupNTAccountArgumentCompleter
Register-ArgumentCompleter -CommandName Export-ADGroupMemberObjects -ParameterName GroupNTAccount -ScriptBlock $GroupNTAccountArgumentCompleter
Export-ModuleMember -Function @('Get-ADGroupMemberObjects')
Export-ModuleMember -Function @('Export-ADGroupMemberObjects')