Private/Get/Get-RootDSE.ps1

function Get-RootDSE {
    <#
        .SYNOPSIS
        Retrieves the RootDSE object for an Active Directory forest.
 
        .DESCRIPTION
        Connects to the RootDSE (Root Directory Service Entry) of the specified Active
        Directory forest. RootDSE contains metadata about the directory such as naming
        contexts, schema information, and forest capabilities.
         
        Uses module-level $script:Forest and $script:Credential variables set by
        Invoke-Locksmith2 via New-LDAPSearcher.
 
        .INPUTS
        None. This function does not accept pipeline input.
 
        .OUTPUTS
        System.DirectoryServices.DirectoryEntry
        Returns a DirectoryEntry object representing the RootDSE.
 
        .EXAMPLE
        Get-RootDSE
        Retrieves the RootDSE for the target forest using script-scope variables.
 
        .NOTES
        Requires script-scope variables set by Invoke-Locksmith2:
        - $script:Forest: Target forest FQDN
        - $script:Credential: AD authentication credentials
         
        The RootDSE is a special object that provides information about the directory
        service. The function uses New-LDAPSearcher which handles credential binding.
 
        .LINK
        https://learn.microsoft.com/en-us/windows/win32/adsi/rootdse
    #>

    [CmdletBinding()]
    param (
        [string]$Forest,
        [System.Management.Automation.PSCredential]$Credential
    )

    #requires -Version 5.1

    # Use script-scoped variables if parameters not provided
    if (-not $Forest -and $script:Forest) {
        $Forest = $script:Forest
    }
    if (-not $Credential -and $script:Credential) {
        $Credential = $script:Credential
    }

    $maxRetries = 3
    $attempt = 0
    $connected = $false

    while (-not $connected -and $attempt -lt $maxRetries) {
        $attempt++
        
        # Get the configuration naming context
        if ($Forest) {
            if ($Credential) {
                $rootDSE = New-Object DirectoryServices.DirectoryEntry(
                    "LDAP://$Forest/RootDSE",
                    $Credential.UserName,
                    $Credential.GetNetworkCredential().Password
                )
            } else {
                $rootDSE = [ADSI]"LDAP://$Forest/RootDSE"
            }
            $Solution = "Could not connect to Active Directory forest: $Forest. Check the value provided for -Forest and/or -Credential."
        } else {
            $rootDSE = [ADSI]"LDAP://RootDSE"
            $Forest = [System.Environment]::UserDomainName
            $Solution = 'The current user is not a member of a domain. Provide values for -Forest and -Credential.'
        }

        # Getting configNC fails silently, so we have to check this manually instead of a try/catch
        if (-not $rootDSE.Name) {
            Write-Warning "$Solution"
            
            if ($attempt -lt $maxRetries) {
                Write-Host "`nAuthentication failed. Please try again. (Attempt $attempt of $maxRetries)" -ForegroundColor Yellow
                
                # Prompt for corrected values
                $retryForest = Read-Host "Enter fully qualified domain controller/domain/forest name (or press Enter to keep '$Forest')"
                if ($retryForest) {
                    $Forest = $retryForest
                    $script:Forest = $retryForest
                }
                
                Write-Host "`nPowerShell credential request`nEnter your credentials."
                $User = Read-Host "Username in NTAccount format (DOMAIN\username)"
                $Password = Read-Host "Password for user $User" -AsSecureString
                $Credential = [System.Management.Automation.PSCredential]::New($User, $Password)
                $script:Credential = $Credential
            } else {
                $errorRecord = [System.Management.Automation.ErrorRecord]::new(
                    [System.Exception]::new("$Solution Authentication failed after $maxRetries attempts."),
                    'ADConnectionFailed',
                    [System.Management.Automation.ErrorCategory]::AuthenticationError,
                    $Forest
                )
                $PSCmdlet.WriteError($errorRecord)
                return
            }
        } else {
            $connected = $true
            $rootDSE
        }
    }
}