0

I would like to export several multi-value "fields" from Microsoft Active Directory. Instead of defining all "array pointers" manually I want to generate them automatically.

I already checked Powershell outputting array items when interpolating within double quotes and tried out several alterantives but I always get stuck with the expressions

$SearchBases ='dummy.com','dummy2.com'
$csv_file_path = "C:\Test\Export.csv"
$properties_select = ''
$properties_multivalue = 'proxyAddresses','showInAddressBook','memberOf'

# go through each multi_value property and automatically generate 8 fields for upto 8 array elements
ForEach($prop in $properties_multivalue) {
    for ($i=0; $i -le 8; $i++) {
        $properties_select += @{Name=$prop+'_'+$i; Expression={$_.$($prop[$i])}}
    }
}
ForEach($SearchBase in $SearchBases) {
    Get-ADObject -filter 'objectClass -eq "contact"' -SearchBase $SearchBase -properties $properties_multivalue 
    |SELECT-Object $properties_select 
    |Export-Csv -Append -Force -Delimiter ";" -NoClobber -Encoding UTF8 -path $csv_file_path
}

I suspect that i do something wrong at

$properties_select += @{Name=$prop+'_'+$i; Expression={$_.$($prop[$i])}}

Any help/hints are useful.

Thanks Chris

Christian
  • 23
  • 5

1 Answers1

0

Two things you need to fix:

The resulting value of $properties_multivalue will be a string and not an array of hashtables, so change line 3 to:

$properties_select = @()

The second thing is the Expression scriptblock - by the time Select-Object executes inside the second loop, $prop and $i will resolve to memberOf and 8 respectively, the last two values that were assigned to them in the first loop.

To have the individual scriptblocks "remember" the values as they were at the time of assignment, you'll need to close over them with the GetNewClosure() method:

$properties_select += @{Name=$prop+'_'+$i; Expression={$_.$($prop[$i])}.GetNewClosure()}

Additionally, I think you'll need to reorder the evaluation of the variables inside the Expression to: $($_.$prop)[$i] (ie. reference $_.memberOf first, then grab the value at index $i of that value)

Mathias R. Jessen
  • 157,619
  • 12
  • 148
  • 206
  • First of all thank you for your quick response. Regarding $properties_multivalue = @() I suppose you mean $properties_select, because $properties_select is in line 3 and currently has an empty string regarding GetNewClosure(): Thanks for the fix - i would never have thought it. regarding expression, I changed the expression as suggested $($_.$prop)[$i] but i still have one challenge with the expor in regards to ,'showInAddressBook','memberOf','postOfficeBox','postalAddress','otherTelephone' it seems, these fields are multi-value but not indexed. – Christian Jun 10 '18 at 20:41
  • @Christian correct, updated the answer to mention `$properties_select`. Can you describe in more detail what your "challenge" is regarding these additional properties? – Mathias R. Jessen Jun 10 '18 at 20:44
  • Currently i get the following output for e.g. memberOf: memberOf1|memberof2|memberOf3|MemberOf4|.... C|N|=|T|.... It devides the DN into individual characters Thus my bestguess multivalue but not indexed if i use $properties_select += @{Name="$prop"; Expression={$($_.$prop) -join ";"}.GetNewClosure()} instead, i get the error message "you must provide a value expression following the '-join' operator." – Christian Jun 10 '18 at 20:49
  • The other issue was caused by something else thus I mark this question as resolved Thanks @Matthias for the help! – Christian Jun 13 '18 at 18:16