functions/utility/Get-PrincipalInformation.ps1

function Get-PrincipalInformation {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory = $true)]
        [string]
        $Identity,

        [string]
        $Server,

        [pscredential]
        $Credential
    )
    $adParameters = $PSBoundParameters | ConvertTo-PSFHashtable -Include Server, Credential

    try { $principal = Resolve-Principal @adParameters -Name $Identity -ErrorAction Stop }
    catch { throw }

    if ($script:identityCache[$principal.DistinguishedName]) {
        return $script:identityCache[$principal.DistinguishedName]
    }

    $groupMembership = Get-ADGroup -LDAPFilter "(member:1.2.840.113556.1.4.1941:=$($principal.DistinguishedName))"

    $properties = 'PasswordLastSet', 'PasswordNeverExpires', 'badPwdCount', 'LastBadPasswordAttempt', 'SamAccountName', 'ObjectSID', 'DistinguishedName'
    $object = Get-ADObject @adParameters -Identity $principal.DistinguishedName -Properties $properties | ConvertTo-PSFHashtable -Include $properties
    $object.GroupMembership = $groupMembership.SID.Value

    $object = [PSCustomObject]$object
    Add-Member -InputObject $object -MemberType ScriptMethod -Name ToString -Value {
        $this.SamAccountName
    } -Force

    $script:identityCache[$principal.DistinguishedName] = $object
    $object
}