1

I have multiple duplicated lines of code, where only "office" name should be different, but criteria which are in the $paste variable should be the same.

$paste = "extensionAttribute -eq 123"
$users1 = get-aduser -Properties canonicalName -filter {(office -like "ROFL") -and ( $paste )}
$users2 = get-aduser -Properties canonicalName -filter {(office -like "BOFL") -and ( $paste )}

While I'm trying to do so (insert the content of $paste variable) I'm receiving this kind of error:

get-aduser : Error parsing query: '(office -like "ROFL") -and ( $paste )' Error Message: 'syntax error'
at position: '47'.
At line:1 char:10
+ $users = get-aduser -Properties canonicalName...
+          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ParserError: (:) [Get-ADUser], ADFilterParsingException
    + FullyQualifiedErrorId : ActiveDirectoryCmdlet:Microsoft.ActiveDirectory.Management.ADFilterParsingException,Microsoft.ActiveDirectory.Management.Commands.GetADUser

How can I avoid this manual inserting every time when I need to change only part of the criteria?

Near Future
  • 175
  • 1
  • 8

1 Answers1

2

Use an expandable string ("..."), not a script block ({ ... })

-Filter "(office -like 'ROFL') -and ( $paste )"

As an aside: since 'ROFL' is not a wildcard expression, there's no benefit to using -like over -eq.

That way, the AD provider ends up seeing the following filter, which should work as expected: (office -like 'ROFL') -and ( extensionAttribute -eq 123 )


As for what you tried:

The use of script blocks ({ ... }) with the AD cmdlets' -Filter parameter is widespread, but conceptually problematic: see this answer.

In short: the -Filter parameter is string-typed, and when you pass it a script block, its verbatim contents - excluding { an } - is passed.

That is, in your attempt the AD provider sees the following string as the -Filter argument verbatim: (office -like "ROFL") -and ( $paste ) - and this string is obviously syntactically incorrect, because the $paste variable you wanted to be expanded (interpolated) up front was not expanded.

When using -Filter, it is important to remember:

  • You'll invariably pass a string as the argument; if you pass a script block, .ToString() is called on it first, yielding its verbatim contents.

  • The use of a script block can give the mistaken impression that you can pass arbitrary PowerShell expressions as the filter, which is not true:

    • While the expression language supported by the -Filter parameter is PowerShell-like, it only supports only a limited subset of operators and the supported operators in part behave differently than their PowerShell counterparts - again, see this answer.

    • The most notable limitation is that you can only use simple variable references (which you cannot even use when you're using implicit remoting), not variable-based expressions, such as property access; e.g., you can use $var in a filter, but you cannot use $var.Foo - use an auxiliary variable in that case.

mklement0
  • 382,024
  • 64
  • 607
  • 775