The ForEach-Object cmdlet requires pipeline input, which you're not providing (in its absence, the script block is called once, which means there is no point in using ForEach-Object at all).
Also, since you need per-element processing of your $split array, you must enumerate it, which the pipeline does for you automatically, as Jeroen Mostert's comment implies:
# Enumerate the elements of array $split, i.e. send
# its elements one by one to ForEach-Object, which sees each as $_
# Note: You can capture the results in a variable simply by
# uncommenting the next line:
# $emailAddresses =
$split | ForEach-Object { $mail + $_ + $domain }
Note the use of the automatic $_ variable, which refers to the current pipeline input object in each iteration.
However, with values already in memory it is more efficient to use the foreach statement:
# Note: You can capture the results in a variable simply by
# uncommenting the next line:
# $emailAddresses =
foreach ($index in $split) { $mail + $index + $domain }
Note the need to specify the input as part of the (...) expression, and the need to name a self-chosen enumeration (iterator) variable.
Finally, a concise and efficient but somewhat obscure solution is to use the regex-based -replace operator:
# Note: You can capture the results in a variable simply by
# uncommenting the next line:
# $emailAddresses =
$split -replace '^', $mail -replace '$', $domain
This relies on -replace being able to operate on arrays as input, in which case the replacement operation is performed on each element, resulting in a transformed array as output.
Regex ^ matches the start of a string, $ matches the end, so that the two operations effectively prepend / append the value of $mail / $domain to each element of $split.
2..100 | ForEach-Object { "test_ " + $_ + "@test.com" }.