When you work with DirectoryEntry objects (AD or local accounts), you quickly run into the fact that their properties are actually PropertyValueCollections. This trips you up with certain operations, like exporting entries. For instance, the following will not work:
# Get some user accounts
$Users = ([ADSI]‘WinNT://.‘).PSBase.Children | where {$_.PSBase.SchemaClassName -eq ‘User‘}
# Export them to a CSV file
$Users | Export-Csv Users.csv
There are no errors, but the exported file will be filled with the text “System.DirectoryServices.PropertyValueCollection”. Not really what we were looking for. The solution is to let PowerShell turn those PropertyValueCollections into regular values. If we just want to get the names and descriptions, we can use:
$Users | select {$_.Name}, {$_.Description} | Export-Csv Users.csv
That’s good enough when you are in a hurry. But if you want the actual property names, and need many (or all) properties, this calls for a scripted solution. This is the version I came up with originally:
filter Select-Properties ($filter='*') { # Create a custom object to hold the requested properties $custom = New-Object PSObject # Get the properties of the object being processed $props = $_.PSBase.Properties # Add each property that matches our filter to the custom object $filter | foreach { $props.PropertyNames -like $_ | foreach { $custom | add-Member noteProperty $_ $($props.Item($_)) } } # Return the custom object $custom }
Now you can use
$Users | Select-Properties | Export-Csv Users.csv
and get the data you really wanted. You can also specify one or more specific properties (with wildcards), just like the Select-Object command. The script has a few drawbacks, but we will save that (and an improved script) for a future post.
Arnoud