2

I can't seem to figure out how to use a variable in a herestring, and for the variable to be expanded at a later time in a piped command. I have experimented with single ' and double " quotes, and escape ` characters.

I am trying to use the herestring for a list (e.g. like an array) of Exchange groups, and a corresponding list of conditions to apply to those groups. Here is a simplified example which fails to use the $Conditions variable correctly (it does not expand the $_.customattribute2 variable):

# List of groups and conditions (tab delimitered)
$records = @"
Group1  {$_.customattribute2 -Like '*Sales*'}
Group2  {$_.customattribute2 -Like '*Marketing*' -OR $_.customattribute2 -Eq 'CEO'}
"@

# Loop through each line in $records and find mailboxes that match $conditions
foreach ($record in $records -split "`n") {
    ($DGroup,$Conditions) = $record -split "`t"

    $MailboxList = Get-Mailbox -ResultSize Unlimited
    $MailboxList | where $Conditions
}
Ansgar Wiechers
  • 193,178
  • 25
  • 254
  • 328
J. Bond
  • 23
  • 3

2 Answers2

5

No, no that's not going to work. The whole good bit about PowerShell is not having to make everything a string and then drag it to the moon and back trying to get the important stuff back out of the string. {$_.x -eq "y"} is a scriptblock. It's a thing by itself, you don't need to put it in a string.

#Array of arrays. Pairs of groups and conditions
[Array]$records = @(

  ('Group1', {$_.customattribute2 -Like '*Sales*'}),
  ('Group2', {$_.customattribute2 -Like '*Marketing*' -OR $_.customattribute2 -Eq 'CEO'})

)

#Loop through each line in $records and find mailboxes that match $conditions
foreach ($pair in $records) {

        $DGroup, $Condition = $pair

        $MailboxList = Get-Mailbox -ResultSize Unlimited
        $MailboxList | where $Condition
}
TessellatingHeckler
  • 27,511
  • 4
  • 48
  • 87
  • I'd argue that a hashtable would be a more suitable data structure than an array here. – Ansgar Wiechers Nov 04 '17 at 11:32
  • I agree with @AnsgarWiechers, hashtables of group names and conditions would fit more nicely for real world use, and I started writing it as a Hashtable version - but decided that the extra property names and using `{}` unrelated to scriptblocks might obscure the point, so I made it close to the original 'shape' of a list of separated pairs instead. – TessellatingHeckler Nov 04 '17 at 22:38
  • Whilst this probably the better powershell way of doing it, @JosefZ answered my specific question. – J. Bond Nov 06 '17 at 06:42
4

TessellatingHeckler's explanation is right. However, if you insist on herestring, it's possible as well. See the following example (created merely for demonstration):

$records=@'
Group1  {$_.Extension -Like "*x*" -and $_.Name -Like "m*"}
Group2  {$_.Extension -Like "*p*" -and $_.Name -Like "t*"}
'@
foreach ($record in $records -split "`n") {
    ($DGroup,$Conditions) = $record -split "`t"
    "`r`n{0}={1}" -f $DGroup,$Conditions
    (Get-ChildItem | 
        Where-Object { . (Invoke-Expression $Conditions) }).Name
}

Output:

PS D:\PShell> D:\PShell\SO\47108347.ps1

Group1={$_.Extension -Like "*x*" -and $_.Name -Like "m*"}
myfiles.txt

Group2={$_.Extension -Like "*p*" -and $_.Name -Like "t*"}
Tabulka stupnic.pdf
ttc.ps1

PS D:\PShell> 

Caution: some text/code editors could convert tabulators to space sequences!

JosefZ
  • 28,460
  • 5
  • 44
  • 83