1

I'm beginning in PowerShell and trying to make this line working :

(Get-ADUser -Filter {userPrincipalName -eq $($ListUsers[100].UserPrincipalName)} -SearchBase "..." -Properties *).distinguishedName

I tried a lot of different things but nothing worked.

The call of $ListUsers[100].UserPrincipalName) works 100% sure, I tried it outside of the line, so it's just a logical or syntaxic problem.

Could someone tell me how to get it to work ? Thanks

Daycopo
  • 188
  • 1
  • 1
  • 11

1 Answers1

3

Use double quotes.

The -Filter argument to the Get-AD* cmdlets takes a string (!), not a script block (even though it looks like it, because braces can also be used instead of quotes).

Get-ADUser -Filter "userPrincipalName -eq '$($ListUsers[100].UserPrincipalName)'"

This way you get proper variable substitution. Note you must end up with a valid filter string, so putting single quotes around the values is necessary when those values are strings.


If you have many objects to fetch from AD, it can be beneficial to fetch them all in one go, instead of one-by-one in a loop. Consider this:

$ListUsers = @(<# ...list of items... #>)

# build LDAP filter string
$upn_filter = $ListUsers.UserPrincipalName -join ')(userPrincipalName='
$upn_filter = "(|(userPrincipalName=$upn_filter))"

$users = Get-ADUser -LDAPFilter $upn_filter
$users.distinguishedName

This builds an LDAP filter in the following form:

(|(userPrincipalName=A)(userPrincipalName=B)(userPrincipalName=C)(userPrincipalName=D))

which would be able to fetch 4 matching objects from AD in one step. Of course you can also build a "PowerShell-style" filter string, but I find the LDAP syntax a lot easier to handle, and it's shorter.

LDAP filter strings can get pretty long without the server complaining, and doing only one round-trip to the domain controller saves time.

Tomalak
  • 332,285
  • 67
  • 532
  • 628
  • The total size of an LDAP query (not just the query string) can be [up to 10MB](https://stackoverflow.com/a/556711/1202807), which is pretty huge. Still, I have some sample code [here](https://www.gabescode.com/active-directory/2018/12/15/better-performance-activedirectory.html#ask-for-as-much-as-you-can-at-a-time) that shows how to break up the request in blocks of 50 (or any number you want). The code is C#, but it could be translated to PowerShell (PowerShell arrays implement .NET's `IEnumerable`). – Gabriel Luci Sep 06 '19 at 14:35
  • @GabrielLuci Nice, that's my own question you're linking to. :) – Tomalak Sep 06 '19 at 14:42
  • Ha! I didn't even notice. It's awesome when things are still relevant after 10 years :) – Gabriel Luci Sep 06 '19 at 15:10
  • Nice; re "putting single quotes around the values is necessary": worth mentioning that embedded _double_ quotes are also an option - while they need to be escaped, they are helpful for expanded values that may contain single quotes (apostrophes). – mklement0 Sep 06 '19 at 15:29