Summary of issue
I have two variables with the same content, the only difference is how the variable was populated, when i try to use it in exchange management shell i get for one variable an error while the other one works as it should be.
Long explanation - With examples
I created a transport rule to block emails from specific senders, I'm trying to use one line in powershell to add users the the block list.
set-transportrule -identity "whatever" -from @{add="whoever"}
But this doesn't work, i researched it and saw that it's by design, so i gave up on this.set-transportrule -identity "whatever" -from (get-transportrule -identity "whatever").from,"whoever2"
But i again hit a road block.set-transportrule -identity "whatever" -from "whoever1","whoever2"
and it worked beautifully. But this is not what i want I'm trying to add to the existing values.This got me thinking, so i started testing to find the differences between the two arrays
variable1 = "whoever1","whoever2"
and used it like this set-transportrule -identity "whatever" -from $variable1
and it worked as it should be.variable2 = (get-transportrule -identity "whatever").from,"whoever2"
and tried using it set-transportrule -identity "whatever" -from $variable2
, but this didn't work.I compared the variable types and they are identical. Whats going on here? What am i missing
Thanks in advance for any help!
In order to concatenate two arrays flatly, you must use +
:
set-transportrule -identity "whatever" `
-from ((get-transportrule -identity "whatever").from + "whoever2")
Note: Since operator +
can only be used in an expression, the entire -from
argument must be enclosed in (...)
.
By contrast, <array>, <scalar>
creates a 2-element array whose 1st element is <array>
, and whose 2nd element is <scalar>
, which is not your intent.
,
, which is PowerShell's array-construction operator, creates an array with each operand becoming an array element as-is, whether a given operand is a scalar or an array.
By contrast, with an array-valued LHS, +
concatenates the LHS and RHS, by appending the RHS element(s) as additional elements to the LHS (which implicitly creates a new array, given that arrays are fixed-size).
A simplified example:
$arr = 1, 2 # input array
$scalar = 3 # scalar to append
# INCORRECT: Creates *nested* array.
($arr, $scalar).Count # -> 2(!); [0] of the new array contains $arr, [1] $scalar
# Same as: (1, 2), 3
# CORRECT: Creates *flat* array.
($arr + $scalar).Count # -> 3
# Same as: (1, 2) + 3 == 1, 2, 3
Note that you can't tell the difference between $arr, $scalar
and $arr + $scalar
by how they print to the screen, because the implicit output formatting implicitly enumerates an array received as a single input object.
You can make the difference visible by piping to Format-Table
with -Expand CoreOnly
, which suppresses the implicit enumeration and instead prints the properties of any array element itself:
# Flat array: prints as expected.
PS> $arr + $scalar | Format-Table -Expand CoreOnly
1
2
3
# Array with sub-arrays: output reveals the presence of subarrays
PS> $arr, $scalar | Format-Table -Expand CoreOnly
Length LongLength Rank SyncRoot IsReadOnly IsFixedSize IsSynchronized Count
------ ---------- ---- -------- ---------- ----------- -------------- -----
2 2 1 {1, 2} False True False 2
3
For additional information, see the bottom section of this answer.