A PowerShell Version 1.0 script to search Active Directory. The program prompts for the base of the query, the LDAP syntax filter, and a comma delimited list of attribute values to retrieve. The program handles single and multi-valued attributes. The attributes can be strings, DN values, byte arrays, SID values, GUID values, 64-bit integers, 32-bit integers, generalized time values, booleans, and the logonHours attribute. If the 64-bit integers are large enough, they are converted into the equivalent datetime in the local time zone, or into a timespan.
 
When the program prompts for the base of the query, you can enter nothing to search the entire domain. Otherwise, enter the Distinguished Name of an OU or container. If you omit the dc components, the program appends the DN of the current domain to your base. You can query the schema container by entering cn=Schema,cn=Configuration, or the Sites container by entering cn=Sites,cn=Configuration. To target a specific domain controller (because you are retrieving attributes that are not replicated, like lastLogon), enter the NetBIOS name of the DC, followed by a forward slash, and then the Distinguished Name of the base of the query.
 
When the program prompts for the LDAP syntax filter, enter any standard filter, where clauses are enclosed in parentheses. For example, to filter on all user objects, you would enter: (&(objectCategory=person)(objectClass=user)). For more information on LDAP syntax filters, see this link: http://www.rlmueller.net/ADOSearchTips.htm
 
When prompted for the comma delimited list of attribute values to retrieve, enter the LDAP Display Names of the attributes. The distinguishedName attribute is always included, so don't specify it. If any attributes are listed twice, the duplicates are not removed. Do not specify the tokenGroups attribute, or an error will be raised.
 
When you run the program, you can specify any of three optional parameter. You can specify either /csv or -csv, to indicate that the output should be in comma delimited format. Otherwise, the output is in a list format. If you do not specify /csv, the program indicates the number of objects found. You can specify /OneLevel or -OneLevel to assign the scope of the query as "oneLevel", rather than the default "subTree". Or, you can specify /Count or -Count to just retrieve the number of objects that match the filter in the base of the query. In many cases you will want to redirect the output to a text file.
 
An error is raised if you are not authenticated to a domain, if the base is invalid, or if the filter is invalid. If you request a non-existent attribute, the values retrieved will be <no value>.

 

PowerShell
Edit|Remove
# GenericSearch.ps1 
# PowerShell program to search Active Directory. 
# Author: Richard Mueller 
# PowerShell Version 1.0 
# August 16, 2011 
# March 20, 2013 - Modify rounding of local time zone bias, 
#                  Fix Function OctetToGUID. 
# May 1, 2013 - Account for negative time zone bias. 
# May 2, 2013 - Handle multi-line strings in csv format. 
# January 25, 2015 - Handle Int64 values likely to be a time span. 
# March 27, 2015 - Improve Function OctetToHours, add functions. 
 
Trap 
{ 
    If ("$_".StartsWith("There is no such object on the server")) 
    { 
        "Invalid Base for the Query: $BaseDN" 
        Break 
    } 
    If ("$_".StartsWith("An invalid dn syntax has been specified")) 
    { 
        "Invalid Base for the Query: $BaseDN" 
        Break 
    } 
    If ("$_".StartsWith("The server is not operational")) 
    { 
        "DC not found: $BaseDN" 
        Break 
    } 
    If ("$_".EndsWith("search filter is invalid.")) 
    { 
        "Invalid LDAP Syntax Filter: $Filter" 
        Break 
    } 
    If ("$_".StartsWith("The directory service is unavailable")) 
    { 
        "Invalid LDAP Syntax Filter: $Filter" 
        Break 
    } 
    If ("$_".StartsWith("An operations error occurred.")) 
    { 
        "You cannot retrieve the value of a multi-valued operational attribute" 
        Break 
    } 
    If ("$_".StartsWith("The attribute syntax specified to the directory service is invalid.")) 
    { 
        "An LDAP Syntax Filter cannot include operational attributes: $Filter" 
        Break 
    } 
    If ("$_".StartsWith("Unknown error (0x80005000)")) 
    { 
        "Domain cannot be contacted. Check network connection and if you are authenticated to a domain." 
        Break 
    } 
    If ("$_".StartsWith("The specified domain either does not exist or")) 
    { 
        "Domain cannot be contacted: $BaseDN" 
        Break 
    } 
    If ("$_".StartsWith("A referral was returned from the server")) 
    { 
        "Base of the query cannot be contacted: $BaseDN" 
        Break 
    } 
    If ("$_".StartsWith("There is no such object on the server")) 
    { 
        "Invalid Base for the Query: $BaseDN" 
        Break 
    } 
    "Error: $_"Break; 
} 
 
$Colon = ":" 
# Check for optional parameters indicating output should be in csv format instead 
# of text, or only a count of the number of records retrieved should be reported, 
# or if the scope of the query should be "oneLevel" rather than "subTree". 
$Csv = $False 
$Count = $False 
$Scope = "subTree" 
 
$Abort = $False 
ForEach ($Arg In $Args) 
{ 
    Switch ($Arg.ToLower()) 
    { 
        {($_ -eq "/csv"-Or ($_ -eq "-csv")} {$Csv = $True} 
        {($_ -eq "/count"-Or ($_ -eq "-count")} {$Count = $True} 
        {($_ -eq "/onelevel"-Or ($_ -eq "-onelevel")} {$Scope = "oneLevel"} 
        Default {"Invalid parameter: $Arg"$Abort = $TrueBreak} 
    } 
} 
If ($Abort -eq $True) {BreakIf (($Csv -eq $True-And ($Count -eq $True)) 
{ 
    "Output cannot be in CSV format if Count is requested" 
    Break 
} 
 
# Retrieve local Time Zone bias from machine registry in hours. 
# This bias does not change with Daylight Savings Time. 
$Bias = (Get-ItemProperty ` 
    -Path HKLM:\System\CurrentControlSet\Control\TimeZoneInformation).Bias 
# Account for negative bias. 
If ($Bias -gt 10080){$Bias = $Bias - 4294967296} 
$Bias = [Math]::Round($Bias/60, 0, [MidpointRounding]::AwayFromZero) 
 
# Create an array of 168 bytes, representing the hours in a week. 
$LH = New-Object 'object[]' 168 
 
Function OctetToGUID ($Octet) 
{ 
    # Function to convert Octet value (byte array) into string GUID value. 
    $GUID = [GUID]$Octet 
    Return $GUID.ToString("B") 
} 
 
Function OctetToHours ($Octet) 
{ 
    # Function to convert Octet value (byte array) into binary string 
    # representing logonHours attribute. The 168 bits represent 24 hours 
    # per day for 7 days, Sunday through Saturday. The values are converted 
    # into local time. If the bit is "1", the user is allowed to logon 
    # during that hour. If the bit is "0", the user is not allowed to logon. 
    For ($j = 0; $j -le 20; $j = $j + 1) 
    { 
        For ($k = 7; $k -ge 0; $k = $k - 1) 
        { 
            $m = 8*$j + $k - $Bias 
            If ($m -lt 0) {$m = $m + 168} 
            If ($m -gt 167) {$m = $m - 168} 
            If ($Octet[$j-band [Math]::Pow(2, $k)) {$LH[$m] = "1"} 
            Else {$LH[$m] = "0"} 
        } 
    } 
 
    For ($j = 0; $J -le 20; $j = $J + 1) 
    { 
        $n = 8*$j 
        Switch ($j) 
        { 
            0 {$Hours = " M   4    8   N    4   8`r`n    Sunday:    " + [String]::Join(""$LH[$n..($n + 7)])} 
            3 {$Hours = $Hours + "`r`n    Monday:    " + [String]::Join(""$LH[$n..($n + 7)])} 
            6 {$Hours = $Hours + "`r`n    Tuesday:   " + [String]::Join(""$LH[$n..($n + 7)])} 
            9 {$Hours = $Hours + "`r`n    Wednesday: " + [String]::Join(""$LH[$n..($n + 7)])} 
            12 {$Hours = $Hours + "`r`n    Thursday:  " + [String]::Join(""$LH[$n..($n + 7)])} 
            15 {$Hours = $Hours + "`r`n    Friday:    " + [String]::Join(""$LH[$n..($n + 7)])} 
            18 {$Hours = $Hours + "`r`n    Saturday:  " + [String]::Join(""$LH[$n..($n + 7)])} 
           Default {$Hours = $Hours + "-" + [String]::Join(""$LH[$n..($n + 7)])} 
        } 
    } 
    Return $Hours 
} 
 
Function UAC ($Flag) 
{ 
    # Function to evaluate the userAccountControl attribute. 
    $Setting = "" 
    If ($Flag -band 0x02) {$Setting = $Setting + "AccountDisabled "} 
    If ($Flag -band 0x08) {$Setting = $Setting + "HomeDirReqd "} 
    If ($Flag -band 0x10) {$Setting = $Setting + "LockedOut "} 
    If ($Flag -band 0x20) {$Setting = $Setting + "PwdNotReqd "} 
    If ($Flag -band 0x40) {$Setting = $Setting + "PwdCannotChg "} 
    If ($Flag -band 0x80) {$Setting = $Setting + "EncriptedTextPwdAllowed "} 
    If ($Flag -band 0x100) {$Setting = $Setting + "TempDuplAccount "} 
    If ($Flag -band 0x200) {$Setting = $Setting + "NormalAccount "} 
    If ($Flag -band 0x800) {$Setting = $Setting + "InterdomnainTrustAcct "} 
    If ($Flag -band 0x1000) {$Setting = $Setting + "WorkstationTrustAcct "} 
    If ($Flag -band 0x2000) {$Setting = $Setting + "ServerTrustAcct "} 
    If ($Flag -band 0x10000) {$Setting = $Setting + "PwdDoesNotExpire "} 
    If ($Flag -band 0x20000) {$Setting = $Setting + "MNSLogonAcct "} 
    If ($Flag -band 0x40000) {$Setting = $Setting + "SmartcardReqd "} 
    If ($Flag -band 0x80000) {$Setting = $Setting + "TrustedForDelgation "} 
    If ($Flag -band 0x100000) {$Setting = $Setting + "NotDelegated "} 
    If ($Flag -band 0x200000) {$Setting = $Setting + "UseDESKeyOnly "} 
    If ($Flag -band 0x400000) {$Setting = $Setting + "RequirePreauth "} 
    If ($Flag -band 0x800000) {$Setting = $Setting + "PwdExpired "} 
    If ($Flag -band 0x1000000) {$Setting = $Setting + "TrustedToAuthForDelegation "} 
    If ($Flag -band 0x4000000) {$Setting = $Setting + "PartialSecretsAcct "} 
    If ($Flag -band 0x8000000) {$Setting = $Setting + "UseAESKeysOnly "} 
    Return " (" + $Setting.Trim() + ")" 
} 
 
Function GroupType ($Flag) 
{ 
    $GT = "" 
    # Function to retrieve group type from the groupType attribute. 
    If ($Flag -band 0x01) {$GT = $GT + "Built-in "} 
    If ($Flag -band 0x02) {$GT = $GT + "Global "} 
    If ($Flag -band 0x04) {$GT = $GT + "Local "} 
    If ($Flag -band 0x08) {$GT = $GT + "Universal "} 
    If ($Flag -band 0x10) {$GT = $GT + "APP_BASIC "} 
    If ($Flag -band 0x20) {$GT = $GT + "APP_QUERY "} 
    If ($Flag -band 0x80000000) {$GT = $GT.Trim() + "/Security"} 
    Else {$GT = $GT.Trim() + "/Distribution"} 
    Return " ($GT)" 
} 
 
Function SearchFlags ($Flag) 
{ 
    $SF"" 
    # Function to evaluate the searchFlags attribute. 
    If ($Flag -band 0x01) {$SF = $SF + "Indexed "} 
    If ($Flag -band 0x02) {$SF = $SF + "IndexedEachContainer "} 
    If ($Flag -band 0x04) {$SF = $SF + "InANRSet "} 
    If ($Flag -band 0x08) {$SF = $SF + "PreservedInTombstone "} 
    If ($Flag -band 0x10) {$SF = $SF + "CopiedWhenObjectCopied "} 
    If ($Flag -band 0x20) {$SF = $SF + "TupleIndex "} 
    If ($Flag -band 0x40) {$SF = $SF + "VLVIndex "} 
    Return " (" + $SF.Trim() + ")" 
} 
 
Function SystemFlags ($Flag) 
{ 
    $SysF = "" 
    # Function to evaluate the systemFlags attribute. 
    If ($Flag -band 0x01) {$SysF = $SysF + "AttrReplicated/NTDSCrossRefObj "} 
    If ($Flag -band 0x02) {$SysF = $SysF + "ReplToGC/DomainCrossRefObj "} 
    If ($Flag -band 0x04) {$SysF = $SysF + "AttrConstructed "} 

    If ($Flag -band 0x10) {$SysF = $SysF + "AttrInBaseSchema "} 
    If ($Flag -band 0x02000000) {$SysF = $SysF + "DelImmediately "} 
    If ($Flag -band 0x04000000) {$SysF = $SysF + "CannotBeMoved "} 
    If ($Flag -band 0x08000000) {$SysF = $SysF + "CannotBeRenamed "} 
    If ($Flag -band 0x10000000) {$SysF = $SysF + "CanBeMovedWithRestrictions "} 
    If ($Flag -band 0x20000000) {$SysF = $SysF + "CanBeMoved "} 
    If ($Flag -band 0x40000000) {$SysF = $SysF + "CanBeRenamed "} 
    If ($Flag -band 0x80000000) {$SysF = $SysF + "CannotBeDeleted "} 
    Return " (" + $SysF.Trim() + ")" 
} 
 
Function SAMType ($Flag) 
{ 
    # Function to evaluate the sAMAccountType attribute. 
    Switch ($Flag) 
    { 
        0x10000000 {$ST = "GroupObject"} 
        0x10000001 {$ST = "NonSecurityGroupObject"} 
        0x20000000 {$ST = "AliasObject"} 
        0x20000001 {$ST = "NonSecurityAliasObject"} 
        0x30000000 {$ST = "UserAccount"} 
        0x30000001 {$ST = "MachineAccount"} 
        0x30000002 {$ST = "TrustAccount"} 
        0x40000000 {$ST = "AppBasicAccount"} 
        0x40000001 {$ST = "AppQueryAccount"} 
    } 
    Return " ($ST)" 
} 
 
Function InstanceType ($Flag) 
{ 
    $IT"" 
    # Function to evaluate the searchFlags attribute. 
    If ($Flag -band 0x01) {$IT = $IT + "NCHead "} 
    If ($Flag -band 0x02) {$IT = $IT + "ReplicaNotInstantiated "} 
    If ($Flag -band 0x04) {$IT = $IT + "Writeable "} 
    If ($Flag -band 0x08) {$IT = $IT + "NCAboveHeld "} 
    If ($Flag -band 0x10) {$IT = $IT + "NCBeingConstructed "} 
    If ($Flag -band 0x20) {$IT = $IT + "NCBeingRemoved "} 
    Return " (" + $IT.Trim() + ")" 
} 
 
$Searcher = New-Object System.DirectoryServices.DirectorySearcher 
$Searcher.PageSize = 200 
$Searcher.SearchScope = $Scope 
 
# Prompt for base of query. 
$BaseDN = Read-Host "Enter DN of base of query, or blank for entire domain" 
If ($BaseDN -eq "") 
{ 
    # Default to the entire domain. 
    $Base = New-Object System.DirectoryServices.DirectoryEntry 
    $BaseDN = $Base.distinguishedName 
} 
Else 
{ 
    If ($BaseDN.ToLower().Contains("dc="-eq $False) 
    { 
        $Domain = New-Object System.DirectoryServices.DirectoryEntry 
        $BaseDN = $BaseDN + "," + $Domain.distinguishedName 
        $BaseDN = $BaseDN.Replace(",,"",").Replace("/,""/") 
    } 
    $Base = New-Object System.DirectoryServices.DirectoryEntry "LDAP://$BaseDN" 
} 
$Searcher.SearchRoot = $Base 
 
# Prompt for LDAP syntax filter. 
$Filter = Read-Host "Enter LDAP syntax filter" 
If ($Filter.StartsWith("("-eq $False) {$Filter = "(" + $FilterIf ($Filter.EndsWith(")"-eq $False) {$Filter = $Filter + ")"$Searcher.Filter = $Filter 
 
$Searcher.PropertiesToLoad.Add("distinguishedName") > $Null 
If ($Count -eq $False) 
{ 
    # Prompt for attributes. 
    $Attributes = Read-Host "Enter comma delimited list of attribute values to retrieve" 
    # Remove any spaces. 
    $Attributes = $Attributes -replace " """ 
    $arrAttrs = $Attributes.Split(",") 
    ForEach ($Attr In $arrAttrs) 
    { 
        If ($Attr -ne "") { $Searcher.PropertiesToLoad.Add($Attr) > $Null } 
    } 
} 
 
If ($Csv -eq $False) 
{ 
    "Base of query: $BaseDN ($Scope)" 
    "Filter: $Filter" 
    If ($Count -eq $False) 
    { 
        "Attributes: $Attributes" 
    } 
    "----------------------------------------------" 
} 
Else 
{ 
    # Header line. 
    $Line = "DN" 
    ForEach ($Attr In $arrAttrs) 
    { 
        If ($Attr -ne "") { $Line = $Line + "," + $Attr } 
    } 
    $Line 
} 
 
# Run the query. 
$Results = $Searcher.FindAll() 
 
If ($Count -eq $True) 
{ 
    $Records = $Results.Count 
    "Number of objects found: $Records" 
    Break 
} 
 
# Enumerate resulting recordset. 
$Records = 0 
ForEach ($Result In $Results) 
{ 
    $Records = $Records + 1 
    $DN = $Result.Properties.Item("distinguishedName") 
    If ($Csv -eq $True) 
    { 
        # Any double quote characters in the DN must be doubled. 
        $Line = """" + $DN[0].Replace(""""""""""+ """" 
    } 
    Else 
    { 
        "DN: " + $DN 
    } 
    # Retrieve all requested attributes. 
    ForEach ($Attr In $arrAttrs) 
    { 
        If ($Attr -ne "") 
        { 
            $Values = $Result.Properties.Item($Attr) 
            If ($Values[0] -eq $Null) 
            { 
                # Attribute has no value. 
                If ($Csv -eq $True) {$Line = "$Line,<no value>"} 
                Else {"  $Attr$Colon <no value>"} 
            } 
            Else 
            { 
                # Attribute might be multi-valued. Values will be semicolon delimited. 
                # Values will only be quoted if they are String. 
                $Multi = "" 
                $Quote = $False 
                ForEach ($Value In $Values) 
                { 
                    Switch ($Value.GetType().Name) 
                    { 
                        "Int64" 
                        { 
                            # Attribute is Integer8 (64-bit). 
                            If (($Value -ge [TimeSpan]::MaxValue.Ticks) ` 
                                -or ($Value -le [TimeSpan]::MinValue.Ticks)) 
                            { 
                                # Value is maximum 64-bit value 2^63 - 1, 
                                # or minimum 64-bit value -2^63. 
                                If ($Csv -eq $True) 
                                    { 
                                    If ($Multi -eq "") {$Multi = "<never>"} 
                                    Else {$Multi = "$Multi;<Never>"} 
                                } 
                                Else {"  $Attr$Colon <never>"} 
                            } 
                            Else 
                            { 
                                If (($Value -gt 120000000000000000) ` 
                                    -and ($Value -le [DateTime]::MaxValue.Ticks)) 
                                { 
                                    # Integer8 value is a date, greater than 
                                    # April 07, 1981, 9:20 PM UTC 
                                    # and less than December 31, 9999 12:00 PM 
                                    $Date = [Datetime]$Value 
                                    If ($Csv -eq $True) 
                                    { 
                                        If ($Multi -eq "") 
                                        { 
                                            $Multi = $Date.AddYears(1600).ToLocalTime() 
                                        } 
                                        Else 
                                        { 
                                            $Multi = "$Multi;" ` 
                                                + $Date.AddYears(1600).ToLocalTime() 
                                        } 
                                    } 
                                    Else 
                                    { 
                                        "  $Attr$Colon " + '{0:n0}' -$Value ` 
                                            + " (" + $Date.AddYears(1600).ToLocalTime() + ")" 
                                    } 
                                } 
                                Else 
                                { 
                                    # Integer8 value, not a date. 
                                    If ($Value -lt 0) 
                                    { 
                                        # Assume a TimeSpan. 
                                        $Span = [TimeSpan](-$Value) 
                                        If ($Csv -eq $True) 
                                        { 
                                            If ($Multi -eq "") {$Multi = $Span} 
                                            Else {$Multi = "$Multi;" + $Span} 
                                        } 
                                        Else 
                                        { 
                                            "  $Attr$Colon " + '{0:n0}' -$Value ` 
                                                + " ($Span Days.Hours:Minutes:Seconds)" 
                                        } 
                                    } 
                                    Else 
                                    { 
                                        # Large integer value, between 0 and 120,000,000,000,000,000. 
                                        If ($Csv -eq $True) 
                                        { 
                                            If ($Multi -eq "") {$Multi = '{0:n0}' -$Value} 
                                            Else {$Multi = "$Multi;" + '{0:n0}' -$Value} 
                                        } 
                                        Else {"  $Attr$Colon " + '{0:n0}' -$Value} 
                                    } 

                                } 
                            } 
                        } 
                        "Byte[]" 
                        { 
                            # Attribute is a byte array (OctetString). 
                            If (($Value.Length -eq 16) ` 
                                -and ($Attr.ToUpper().Contains("GUID"-eq $True)) 
                            { 
                                # GUID value. 
                                If ($Csv -eq $True) 
                                { 
                                    If ($Multi -eq "") {$Multi = $(OctetToGUID $Value)} 
                                    Else {$Multi = "$Multi;" + $(OctetToGUID $Value)} 
                                } 
                                Else {"  $Attr$Colon " + $(OctetToGUID $Value)} 
                            } 
                            Else 
                            { 
                                If (($Value.Length -eq 21) -and ($Attr -eq "logonHours")) 
                                { 
                                    # logonHours attribute, byte array of 168 bits. 
                                    # One binary bit for each hour of the week, in UTC. 
                                    If ($Csv -eq $True) 
                                    { 
                                        If ($Multi -eq "") {$Multi = $(OctetToHours $Value)} 
                                        Else {$Multi = "$Multi;" + $(OctetToHours $Value)} 
                                    } 
                                    Else {"  $Attr$Colon " + $(OctetToHours $Value)} 
                                } 
                                Else 
                                { 
                                    If (($Value[0] -eq 1) -and (` 
                                        (($Value[1] -eq 1) -and ($Value.Length -eq 12)) ` 
                                        -or (($Value[1] -eq 2) -and ($Value.Length -eq 16)) ` 
                                        -or (($Value[1] -eq 4) -and ($Value.Length -eq 24)) ` 
                                        -or (($Value[1] -eq 5) -and ($Value.Length -eq 28)))) 
                                    { 
                                        # SID value. 
                                        $SID = New-Object System.Security.Principal.SecurityIdentifier $Value, 0 
                                        If ($Csv -eq $True) 
                                        { 
                                            If ($Multi -eq "") {$Multi = $SID} 
                                            Else {$Multi = "$Multi;$SID"} 
                                        } 
                                        Else {"  $Attr$Colon $SID"} 
                                    } 
                                    Else 
                                    { 
                                        # Byte array. 
                                        If ($Csv -eq $True) 
                                        { 
                                            If ($Multi -eq "") {$Multi = $Value} 
                                            Else {$Multi = "$Multi;$Value"} 
                                        } 
                                        Else {"  $Attr$Colon $Value"} 
                                    } 
                                } 
                            } 
                        } 
                        "String" 
                        { 
                            # String value. Enclose in quotes in case there are embedded 
                            # commas. Any double quote characters in the string must 
                            # be doubled. 
                            $Quote = $True 
                            If ($Csv -eq $True) 
                            { 
                                # Embedded quotes must be doubled. 
                                $Value = $Value.Replace("""""""""") 
                                # Multi-line values must have carriage return line 
                                # feed characters replaced with ";".                          
                                $Value = $Value.Replace("`r`n"";") 
                                If ($Multi -eq "") {$Multi = $Value} 
                                Else {$Multi = "$Multi;$Value"} 
                            } 
                            Else {"  $Attr$Colon $Value"} 
                        } 
                        "Int32" 
                        { 
                            # 32-bit integer. 
                            If (($Attr.ToLower() -eq "useraccountcontrol"-Or ` 
                                ($Attr.ToLower() -eq "msds-user-account-control-constructed")) 
                            { 
                                # If attribute is userAccountControl, append settings. 
                                $Value = "$Value" + $(UAC($Value)) 
                            } 
                            If ($Attr.ToLower() -eq "grouptype") 
                            { 
                                # If attribute is groupType, append settings. 
                                $Value = "$Value" + $(GroupType($Value)) 
                            } 
                            If ($Attr.ToLower() -eq "searchflags") 
                            { 
                                # If attribute is searchFlags, append settings. 
                                $Value = "$Value" + $(SearchFlags($Value)) 
                            } 
                            If ($Attr.ToLower() -eq "systemflags") 
                            { 
                                # If attribute is systemFlags, append settings. 
                                $Value = "$Value" + $(SystemFlags($Value)) 
                            } 
                            If ($Attr.ToLower() -eq "samaccounttype") 
                            { 
                                # If attribute is sAMAccountType, append settings. 
                                $Value = "$Value" + $(SAMType($Value)) 
                            } 
                            If ($Attr.ToLower() -eq "instancetype") 
                            { 
                                # If attribute is instanceType, append settings. 
                                $Value = "$Value" + $(InstanceType($Value)) 
                            } 
                            If ($Csv -eq $True) 
                            { 
                                If ($Multi -eq "") {$Multi = '{0:n0}' -$Value} 
                                Else {$Multi = "$Multi;" + '{0:n0}' -$Value} 
                            } 
                            Else {"  $Attr$Colon " + '{0:n0}' -$Value} 
                        } 
                        "Boolean" 
                        { 
                            # Boolean value. 
                            If ($Csv -eq $True) 
                            { 
                                If ($Multi -eq "") {$Multi = "$Value"} 
                                Else {$Multi = "$Multi;$Value"} 
                            } 
                            Else {"  $Attr$Colon $Value"} 
                        } 
                        "DateTime" 
                        { 
                            # Datetime value. 
                            If ($Csv -eq $True) 
                            { 
                                If ($Multi -eq "") {$Multi = "$Value"} 
                                Else {$Multi = "$Multi;$Value"} 
                            } 
                            Else {"  $Attr$Colon $Value"} 
                        } 
                        Default 
                        { 
                            If ($Csv -eq $True) 
                            { 
                                If ($Multi -eq "") {$Multi = "<not supported> (" + $Value.GetType().Name + ")"} 
                                Else {Multi = "$Multi;<not supported> (" + $Value.GetType().Name + ")"} 
                            } 
                            Else {"  $Attr$Colon <not supported> (" + $Value.GetType().Name + ")"} 
                        } 
                    } 
                } 
                If ($Csv -eq $True) 
                { 
                    # Enclose values in double quotes if necessary. 
                    If ($Quote -eq $True) {$Line = "$Line,""$Multi"""} 
                    Else {$Line = "$Line,$Multi"} 
                } 
            } 
        } 
    } 
    If ($Csv -eq $True) {$Line} 
} 
 
If ($Csv -eq $False) {"Number of objects found: $Records"