Nima Kamkar
Nima Kamkar

Reputation: 33

Problem placing a variable in a cmdlet with "-eq"

I am trying to do something very simple in Exchange 2019 powershell, but for the life of me I cannot seem to get my head around a simple variable placement. The issue has nothing to do with Exchange, just pure PS.

I need to execute the cmdlet

New-AddressList "XX Users" -RecipientFilter {((CustomAttribute2 -eq "XX") -and (RecipientType -eq 'UserMailbox'))}

which is fine, but I want to replace "XX Users" and "XX" with variables.

I can replace "XX Users" by saying something like

$var1 = "XX Users" (this actually works)
$var2 = "XX" (does not work)

so I get

New-AddressList $var1 -RecipientFilter {((CustomAttribute2 -eq $var2) -and (RecipientType -eq 'UserMailbox'))}

for the life of me that $var2 does not insert the correct value for the -eq. I have tried numerous combinations, including using single quote, double quote, where object, moving braces around and I have gotten nowhere. It either takes it as literal or null.

Upvotes: 3

Views: 255

Answers (1)

mklement0
mklement0

Reputation: 438263

The -RecipientFilter parameter is [string]-typed, which means that the literal contents of the script block you pass - everything between the opening { and the closing } - is passed as a value.

That is, no interpolation of variable references such as $var2 takes place, so unless New-AddressList itself actively performs that interpolation by accessing the caller's variables, $var2 will be used verbatim, which is not your intent.

This sounds like the same problem as with AD (Active Directory) filters - see this answer (except that the latter actually do interpolate simple variable references, but not expressions such as $var2.Name, which is why it's better not to rely on that).

As in the AD case, the best approach is to construct your -RecipientFilter argument as a string, specifically as an expandable string ("...") in which you can embed variable values:

# Construct the filter as an *expandable string*.
# Note that $var2 is instantly replaced by its value, so
# you still need quoting around it.
# The assumption is that $var2's value doesn't contain single quotes itself.
$filterString = "((CustomAttribute2 -eq '$var2') -and (RecipientType -eq 'UserMailbox'))"

New-AddressList $var1 -RecipientFilter $filterString

If $var2 may contain ' chars. itself, replace $var2 with an expression that escapes these; if New-AddressList expects the same escaping as PowerShell itself - i.e. doubling ' chars. - replace $var2 with $($var2 -replace "'", "''").


Curiously, as of this writing, the official help topic actively recommends the { ... } syntax without stating its fundamental limitation, and all example commands show filters with literals only. This GitHub issue was created to address that.

Upvotes: 1

Related Questions