Home > front end >  Why does the dot source operator convert strings into commands
Why does the dot source operator convert strings into commands

Time:11-03

I came across a script that obfuscated its calls using the dot sourcing operator.

$ORMEFyak=.('n' 'ew-obje' 'ct') NeT.WebcLIENt;

This seems to be equivalent to: $var = New-Object Net.WebClient

Running . "help" returns the contents of the help cmdlet.

Why exactly does the dot source operator act like this?

CodePudding user response:

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 performed.

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.

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?')

  • Related