Public/Get-UserDomain.ps1

<#
.SYNOPSIS
    Retrieves the domain name for a given SAM account name.
 
.DESCRIPTION
    The `Get-UserDomain` function searches for a user in Active Directory by SAM account name and retrieves the domain name. It accepts an array of search root paths and logs the search process.
 
.PARAMETER SamAccountName
    The SAM account name of the user.
 
.PARAMETER SearchRoots
    An array of search root paths to search in.
 
.PARAMETER LogPath
    (Optional) Path to the log file where log messages will be written.
 
.EXAMPLE
    PS C:\> $domain = Get-UserDomain -SamAccountName "jdoe" -SearchRoots @("GC://dc=test,dc=LOCAL", "GC://dc=testing,dc=LOCAL")
 
    # Returns the Domain Name of the specified user
.EXAMPLE
    PS C:\> $domain = Get-UserDomain -SamAccountName "jdoe" -SearchRoots @("GC://dc=test,dc=LOCAL") -LogPath "C:\path\to\logfile.log"
 
    # In case if LogPath parameter is specified, it will save the results into the specified log file
.NOTES
    N\A
#>


function Get-UserDomain {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory = $true, HelpMessage = "The SAM account name of the user.")]
        [string]$SamAccountName,

        [Parameter(Mandatory = $true, HelpMessage = "An array of search root paths to search in.")]
        [string[]]$SearchRoots,

        [Parameter(Mandatory = $false, HelpMessage = "Path to the log file where log messages will be written.")]
        [string]$LogPath
    )

    if (-not $SearchRoots -or $SearchRoots.Count -eq 0) {
        Write-Log -Message "No search roots provided." -LogPath $LogPath
        Write-Error "No search roots provided."
        return
    }

    # Define the search filter
    $strFilter = "(&(objectCategory=User)(sAMAccountName=$SamAccountName))"

    # Function to perform search
    function Search-AD {
        Param(
            [string]$SearchRoot,
            [string]$Filter,
            [string]$LogPath
        )

        try {
            $objSearcher = New-Object System.DirectoryServices.DirectorySearcher
            $objSearcher.SearchRoot = New-Object System.DirectoryServices.DirectoryEntry($SearchRoot)
            $objSearcher.PageSize = 1000
            $objSearcher.Filter = $Filter
            $objSearcher.SearchScope = "Subtree"

            $results = $objSearcher.FindAll()

            if ($results.Count -gt 0) {
                $searchResult = $results[0].GetDirectoryEntry()
                $distinguishedName = $searchResult.Properties["distinguishedName"][0]
                $domainName = [regex]::Match($distinguishedName, 'DC=([^,]+)').Groups[1].Value
                return $domainName
            } else {
                return $null
            }
        } catch {
            Write-Log -Message "Error searching in $SearchRoot : $_" -LogPath $LogPath
            return $null
        }
    }

    $domain = $null
    foreach ($searchRoot in $SearchRoots) {
        $domain = Search-AD -SearchRoot $searchRoot -Filter $strFilter -LogPath $LogPath
        if ($domain) {
            Write-Log -Message "Found SAM account name $SamAccountName in domain: $domain" -LogPath $LogPath
            break
        }
    }

    if (-not $domain) {
        Write-Log -Message "SAM account name $SamAccountName not found in any domain" -LogPath $LogPath
    }

    return $domain
}