internal/functions/Get-LdapObject.ps1

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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
function Get-LdapObject
{
<#
    .SYNOPSIS
        Use LDAP to search in Active Directory
     
    .DESCRIPTION
        Utilizes LDAP to perform swift and efficient LDAP Queries.
     
    .PARAMETER LdapFilter
        The search filter to use when searching for objects.
        Must be a valid LDAP filter.
     
    .PARAMETER Properties
        The properties to retrieve.
        Keep bandwidth in mind and only request what is needed.
     
    .PARAMETER SearchRoot
        The root path to search in.
        This generally expects either the distinguished name of the Organizational unit or the DNS name of the domain.
        Alternatively, any legal LDAP protocol address can be specified.
     
    .PARAMETER Configuration
        Rather than searching in a specified path, switch to the configuration naming context.
     
    .PARAMETER Raw
        Return the raw AD object without processing it for PowerShell convenience.
     
    .PARAMETER PageSize
        Rather than searching in a specified path, switch to the schema naming context.
     
    .PARAMETER SearchScope
        Whether to search all OUs beneath the target root, only directly beneath it or only the root itself.
     
    .PARAMETER Server
        The server / domain to connect to.
     
    .PARAMETER Credential
        The credentials to use.
     
    .EXAMPLE
        PS C:\> Get-LdapObject -LdapFilter '(PrimaryGroupID=516)'
         
        Searches for all objects with primary group ID 516 (hint: Domain Controllers).
#>

    [CmdletBinding(DefaultParameterSetName = 'SearchRoot')]
    param (
        [Parameter(Mandatory = $true)]
        [string]
        $LdapFilter,
        
        [string[]]
        $Properties = "*",
        
        [Parameter(ParameterSetName = 'SearchRoot')]
        [string]
        $SearchRoot,
        
        [Parameter(ParameterSetName = 'Configuration')]
        [switch]
        $Configuration,
        
        [switch]
        $Raw,
        
        [ValidateRange(1, 1000)]
        [int]
        $PageSize = 1000,
        
        [System.DirectoryServices.SearchScope]
        $SearchScope = 'Subtree',
        
        [string]
        $Server,
        
        [System.Management.Automation.PSCredential]
        $Credential
    )
    
    begin
    {
        $searcher = New-Object system.directoryservices.directorysearcher
        $searcher.PageSize = $PageSize
        $searcher.SearchScope = $SearchScope
        if ($Credential)
        {
            $searcher.SearchRoot.Username = $Credential.UserName
            try { $searcher.SearchRoot.Password = $Credential.GetNetworkCredential().Password }
            catch { Stop-PSFFunction -String 'Get-LdapObject.CredentialError' -ErrorRecord $_ -Cmdlet $PSCmdlet -EnableException $true }
        }
        
        if ($SearchRoot)
        {
            if ($SearchRoot -like "LDAP://*") { $searcher.SearchRoot.Path = $SearchRoot }
            elseif ($SearchRoot -notlike "*=*") { $searcher.SearchRoot.Path = "LDAP://DC={0}" -f ($SearchRoot -split "\." -join ",DC=") }
            else { $searcher.SearchRoot.Path = "LDAP://$($SearchRoot)" }
        }
        
        if ($Configuration)
        {
            $searcher.SearchRoot.Path = "LDAP://CN=Configuration,{0}" -f $searcher.SearchRoot.distinguishedName[0]
        }
        if ($Server -and ($searcher.SearchRoot.Path -notmatch '^LDAP://[\w\.]+/'))
        {
            $searcher.SearchRoot.Path = $searcher.SearchRoot.Path -replace '^LDAP://', "LDAP://$Server/"
        }
        Write-PSFMessage -String Get-LdapObject.SearchRoot -StringValues $SearchScope, $searcher.SearchRoot.Path -Level Debug
        
        $searcher.Filter = $LdapFilter
        
        foreach ($property in $Properties)
        {
            $null = $searcher.PropertiesToLoad.Add($property)
        }
        
        Write-PSFMessage -String Get-LdapObject.Searchfilter -StringValues $LdapFilter -Level Debug
    }
    process
    {
        try
        {
            foreach ($ldapobject in $searcher.FindAll())
            {
                if ($Raw)
                {
                    $ldapobject
                    continue
                }
                $resultHash = @{ }
                foreach ($key in $ldapobject.Properties.Keys)
                {
                    # Write-Output verwandelt Arrays mit nur einem Wert in nicht-Array Objekt
                    $resultHash[$key] = $ldapobject.Properties[$key] | Write-Output
                }
                if ($resultHash.ContainsKey("ObjectClass")) { $resultHash["PSTypeName"] = $resultHash["ObjectClass"] }
                [pscustomobject]$resultHash
            }
        }
        catch
        {
            Stop-PSFFunction -String 'Get-LdapObject.SearchError' -ErrorRecord $_ -Cmdlet $PSCmdlet -EnableException $true
        }
    }
}