The behavior is not specific to .
, the dot-sourcing operator; it equally applies to &
, the call operator.
Only when you're invoking a script file (*.ps1
) (or, less commonly, function or script block) do .
and &
behave differently: .
runs the code directly in the caller's scope, whereas &
, which is more typical, runs it in a child scope - see this answer for more information.
In the case of New-Object
, as a cmdlet, you can technically use them interchangeably (or omit them altogether - see below), but for conceptual clarity it's better to use &
unless actual dot-sourcing is required.
It isn't so much that they convert a string to a command, it is that their purpose is to execute a command given by its name, as a string, among other forms (see below).
The specific syntax used to provide or construct this name for .
or &
is incidental, and in your case a string-concatenation expression was used to obscure the name of the command being invoked.
- However, specifying the name of a command unquoted, verbatim (if syntactically possible) is special in that you can then invoke without an operator -
&
is then implied; see below for an example.
Therefore, all of the following variations are equivalent (for the reasons stated above, I'm using &
):
# Bareword (unquoted, verbatim) command name
# If you don't need dot-sourcing, you can invoke *as-is* -
# use of & is implied.
New-Object regex 'foo?'
# Optionally, use &
& New-Object regex 'foo?'
# If the command name *needs quoting*, is *(based on) a variable* or
# *built by an expression*, & is *required*
$cmd = 'New-Object'
& $cmd regex 'foo?'
& ('New-' + 'Object') regex 'foo?'
Note that in addition to acting on command names (strings), .
and &
can also invoke script blocks (e.g. & { New-Object regex 'foo?' }
) and command-information objects returned by Get-Command
(e.g., & (Get-Command New-Object) regex 'foo?'
)