How to get all fields from Get-ADUser?

Viewed 1609

I have the following code:

$Users = Get-ADUser -Server $Domain -ResultPageSize 500000 -Filter * -Properties *, "msDS-UserPasswordExpiryTimeComputed" |
         Select-Object * -ExcludeProperty *Certificate, PropertyNames,
             *Properties, PropertyCount, Certificates, nTSecurityDescriptor
foreach ($U in $Users) {
    $($U.PSobject.Properties.Name).Count
}

When you check count of properties for each object, it will be different. In the case of my test domain, this ranges from 103 to 147 properties per object.

While I can always add that count to an array, sort of like this:

$Array = @()
foreach ($T in $Test) {
    #Get-ObjectType $T
    $Array += $($T.PSobject.Properties.Name).Count
}

$Array | Sort-Object

And take the highest value and take all named properties from the one with highest properties count and then build my Excel/Word/SQL object based on that... there is:

  1. a chance that the object with highest number of properties count doesn't really have the same properties like the one with the lowest number of properties

  2. a big performance hit (I know that asking for all fields is a performance hit anyway)

Is there some other way to get a full set of results with all fields listed, even if they are empty for some records?

If you're wondering why I may need this think of creating a SQL table that will need all fields defined prior to inserting rows. Or an Excel workbook that will go row by row starting with header (which has to be known).

1 Answers

I've opted for this approach:

function Get-ObjectProperties {
param (
    [object] $Object
)
    $Properties = New-ArrayList
    foreach ($O in $Object) {
        $ObjectProperties = $O.PSObject.Properties.Name
        foreach ($Property in $ObjectProperties) {
            Add-ToArrayAdvanced -List $Properties -Element $Property -SkipNull -RequireUnique
        }
   }
   return $Properties | Sort-Object
}

I've added it to PSSharedGoods module (Install-Module PSSharedGoods) as I also use New-ArrayList, Add-ToArrayAdvanced functions that I've added into that module. It can be probably done without those additional functions but since I already use them a lot I don't mind.

I've tried other stuff like:

$properties = Get-ADObject -SearchBase (Get-ADRootDSE).SchemanamingContext -Filter {name -eq "User"} -Properties MayContain, SystemMayContain | `
    Select-Object @{name = "Properties"; expression = {$_.maycontain + $_.systemmaycontain}} | Select-Object -ExpandProperty Properties

$Test1 = Get-ADUser -Server $Domain -ResultPageSize 5000000 -Filter * -Properties $properties 

Or:

$Test1 = Get-ADObject -SearchBase (Get-ADRootDSE).SchemaNamingContext -Filter {name -like "User"} -Properties MayContain, SystemMayContain |
    Select-Object @{n = "Attributes"; e = {$_.maycontain + $_.systemmaycontain}} | Select-Object -ExpandProperty Attributes | Sort-Object

$Test2 = Get-ADObject -SearchBase (Get-ADRootDSE).SchemaNamingContext -ldapfilter '(systemFlags:1.2.840.113556.1.4.803:=4)' -Properties systemFlags |
    Select-Object Name | Sort-Object Name

But it simply doesn't return everything. The method I used on my simple domain returned 181 properties (from my function). Other methods returned 43 or similar. It still doesn't return everything but it's better than what I had before. For example it returns ExtensionAttribute10 but not others but that's because only 1 object in my AD has that set.

I am not sure how I could be sure to get all possible fields available.

Related