steinybot
steinybot

Reputation: 6134

What is the difference between dot (.) and ampersand (&) in PowerShell?

In PowerShell, what is the difference between using dot (.) and ampersand (&) when invoking a cmdlet, function, script file, or operable program?

For example:

. foo.sh1
& foo.sh1

There is a very similar question which has been incorrectly closed as a duplicate: Differences between ampersand (&) and dot (.) while invoking a PowerShell scriptblock. The questions are different and have completely different keywords and search rankings. The answer on What is the `.` shorthand for in a PowerShell pipeline? only answers half the question.

Upvotes: 59

Views: 21894

Answers (4)

mklement0
mklement0

Reputation: 437638

  • The difference between the . and & operators matters only when calling PowerShell scripts or functions (or their aliases) - for cmdlets and external programs, they act the same.

  • For scripts and functions, . and & differ with respect to scoping of the definition of functions, aliases, and variables:

    • &, the call operator, executes scripts and functions in a child scope, which is the typical use case: functions and scripts are typically expected to execute without side effects:

      • The variables, (nested) functions, aliases defined in the script / function invoked are local to the invocation and go out of scope when the script exits / function returns.

      • Note, however, that even a script run in a child scope can - by explicit action - affect the caller's environment, such as by using Set-Location to change the current location, explicitly modifying the parent scope (Set-Variable -Scope 1 ...) or the global scope ($global:...) or defining process-level environment variables.

    • ., the dot-sourcing operator, executes scripts and functions in the current scope and is typically used to modify the caller's scope by adding functions, aliases, and possibly variables for later use. For instance, this mechanism is used to load the $PROFILE file that initializes an interactive session.

The caveat is that for functions (as opposed to scripts) the reference scope for child vs. current is not necessarily the caller's scope: if the function was defined in a module, the reference scope is that module's scope domain:

  • In other words: trying to use . with a module-originated function is virtually pointless, because the scope getting modified is the module's.
  • That said, functions defined in modules aren't usually designed with dot-sourcing in mind anyway.

Upvotes: 73

js2010
js2010

Reputation: 27423

You can also run things inside a module scope with the call operator, from my notes from Windows Powershell in Action.

# get and variable in module scope
$m = get-module counter
& $m Get-Variable count
& $m Set-Variable count 33

# see func def
& $m Get-Item function:Get-Count

# redefine func in memory
& $m {
  function script:Get-Count
  {
    return $script:count += $increment * 2
  }
}

# get original func def on disk
Import-Module .\counter.psm1 -Force

A few other things:

# run with commandinfo object
$d = get-command get-date
& $d

# call anonymous function
& {param($x,$y) $x+$y} 2 5

# same with dot operator
. {param($x,$y) $x+$y} 2 5

Upvotes: 3

Ranadip Dutta
Ranadip Dutta

Reputation: 9133

To segregate and give a clear understanding, I am explaining a scenario. Imagine you have function named MyFunction in a source.ps1. And you wish to use that function in another script(MyCustomScript.ps1)

Put a line in MyCustomScript.ps1 like the below and you should be able to use it.

. path\of\the\source.ps1 

MyFunction

So you are using the function which is present in source.ps1 in your custom script. Whereas, & is the call operator in Powershell which will help you to call any of the outside executable like psexec and others.

Invoking a command (either directly or with the call operator) will create another scope known as child scope and will be gone once the command been executed. If the command is changing any of the values in a global variable then in that case the changes will be lost when the scope ends as well.

To avoid this drawback and to keep any changes made to global variables you can dot the script which will always execute the script in your current scope.

Dot sourcing will only run the function or script within the current scope and call operator (&) which will run a function or script as usual; but it will never add to the current scope.

Hope this gives an idea on when to use what.

Upvotes: 0

Prasoon Karunan V
Prasoon Karunan V

Reputation: 3043

Like Mathias mentioned as a comment in this thread. & is used to invoke the expression whatever comes after the & and . is used to invoke it in the current scope and is normally used to dot source a helper file which contains functions to make it available in callers scope.

Upvotes: 2

Related Questions