Gabriel Luci's helpful answer provides an effective solution and helpful pointers, but it's worth digging deeper:
Your problem is that you're trying to pass expression $fname+$lname[0]
as an argument, which requires enclosing (...)
:
New-ADuser ... -UserPrincipalName ($fname+$lname[0])
PowerShell has two distinct parsing modes, and when a command (such as New-ADUser
) is called, PowerShell operates in argument mode, as opposed to expression mode.
Enclosing an argument in (...)
forces a new parsing context, which in the case of $fname+$lname[0]
causes it to be parsed in expression mode, which performs the desired string concatenation.
In argument mode, unquoted arguments are implicitly treated as if they were enclosed in "..."
, i.e., as expandable strings under the following circumstances:
- If they don't start with
(
, @
, $(
or @(
.
- If they either do not start with a variable reference (e.g.,
$var
) or do start with one, but are followed by other characters that are considered part of the same argument (e.g., $var+$otherVar
).
Therefore, $fname+$lname[0]
is evaluated as if "$fname+$lname[0]"
had been passed:
- The
+
become part of the resulting string.
- Additionally, given that inside
"..."
you can only use variable references by themselves (e.g., $fname
), not expressions (e.g., $lname[0]
), $lname[0]
won't work as intended either, because the [0]
part is simply treated as a literal.
Embedding an expression (or a command or even multiple expressions or commands) in "..."
requires enclosing it in $(...)
, the subexpression operator, as in Gabriel's answer.
For an overview of PowerShell's string expansion rules, see this answer.
The following examples use the Write-Output
cmdlet to illustrate the different behaviors:
$fname = 'Jane'
$lname = 'Doe', 'Smith'
# WRONG: Same as: "$fname+$lname[0]", which
# * retains the "+"
# * expands array $lname to a space-separated list
# * treats "[0]" as a literal
PS> Write-Output -InputObject $fname+$lname[0]
Jane+Doe Smith[0]
# OK: Use an expression via (...)
PS> Write-Output -InputObject ($fname+$lname[0])
JaneDoe
# OK: Use an (implicit or explicit) expandable string.
PS> Write-Output -InputObject $fname$($lname[0]) # or: "$fname$($lname[0])"
JaneDoe
# OK: Use an intermediate variable:
PS> $userName = $fname + $lname[0]; Write-Output -InputObject $userName