PowerShell Dot Sourcing: Load Scripts into Current Session

PowerShell Dot Sourcing: Load Scripts into Current Session

PowerShell Tips Editor 4 min read
PowerShell Dot Sourcing: Load Scripts into Current Session

Every seasoned PowerShell scripter eventually builds a library of reusable functions — helper utilities, logging wrappers, string formatters. The challenge is getting those functions into your current session without packaging a full module. PowerShell dot sourcing solves this by executing a script inside your current scope rather than an isolated child scope, making every function, variable, and alias defined in that file immediately available to you. This post explains the syntax, shows how dot sourcing differs from a regular script call, and covers the pitfalls that catch new users.

What Dot Sourcing Does

When you run a script normally, PowerShell creates a child scope. Variables and functions defined inside that script vanish when the script finishes. Dot sourcing changes this behavior: the script runs in the current scope, so everything it defines persists after the script exits.

Think of it as copy-pasting the script contents directly into your session — without actually copy-pasting anything. This is the mechanism behind $PROFILE loading and shared function libraries used across multiple automation scripts.

# Regular call — functions disappear after execution
.\MyFunctions.ps1

# Dot source — functions stay in the current scope
. .\MyFunctions.ps1

Dot Source Syntax

The syntax is a dot followed by a space and then the script path. The space is mandatory — without it, PowerShell treats the dot as part of a member-access expression, not a sourcing operator.

# Correct — note the space after the dot
. .\Helpers.ps1
. "C:\Scripts\Helpers.ps1"

# Incorrect — no space, will throw an error or call a method
..\Helpers.ps1

You can also dot source a script block defined inline, which is useful in tests:

$block = { function Get-Greeting { "Hello, $_" } }
. $block
Get-Greeting "World"
Hello, World

Dot Source vs Regular Script Call

The key behavioral difference is scope. A regular call spawns a child scope; dot source does not. This table summarizes what survives after each approach:

  • Regular call: functions, variables, and aliases defined inside are gone after the script exits.
  • Dot source: functions, variables, and aliases persist in the caller’s scope.
# Script: Define-Funcs.ps1
function Get-ServerInfo {
    param([string]$ComputerName)
    Get-CimInstance -ClassName Win32_ComputerSystem -ComputerName $ComputerName |
        Select-Object Name, TotalPhysicalMemory, NumberOfLogicalProcessors
}

# In your session:
. .\Define-Funcs.ps1
Get-ServerInfo -ComputerName "Server01"   # works — function is in scope

Relative vs Absolute Path

Relative paths in dot source are resolved against the current working directory ($PWD), not the script’s own directory. This catches many users off guard when they call a script from a different directory.

The safest pattern for production scripts is to reference the script’s own directory using $PSScriptRoot, which PowerShell sets automatically to the folder containing the running script:

# Inside C:\Scripts\Main.ps1
# $PSScriptRoot is C:\Scripts regardless of where you ran Main.ps1 from
. "$PSScriptRoot\Shared\Helpers.ps1"
. "$PSScriptRoot\Shared\Logging.ps1"

This pattern is portable and works correctly whether you run the script from C:\, C:\Scripts, or a UNC path.

Dot Source in Profile

The PowerShell profile ($PROFILE) is itself a dot-sourced script. You can use the same technique inside your profile to load function libraries every time a new session opens:

# Inside $PROFILE
. "C:\Scripts\MyFunctions.ps1"
. "C:\Scripts\ADHelpers.ps1"

# Now every new session has these functions available automatically

Keep profile-loaded scripts lean. Heavy dot sourcing at profile load time noticeably slows down every new terminal window.

Alternatives: Modules vs Dot Source

Dot sourcing works well for personal libraries and quick sharing between scripts in the same repository. For anything larger or intended for distribution, a PowerShell module is the better choice. Modules offer versioning, auto-loading via $env:PSModulePath, proper help integration, and dependency management.

Use dot source when you want simplicity and the files live alongside your scripts. Use a module when you need versioning, cross-machine deployment, or want Import-Module discoverability.

Common Errors and Fixes

  • Relative paths depend on current working directory. A script calling . .\Helpers.ps1 fails if you run it from a different directory. Fix: use . "$PSScriptRoot\Helpers.ps1" to anchor the path to the script’s own location.
  • Functions overwritten if dot-sourced twice. Dot sourcing the same file a second time silently redefines every function in it, which can hide bugs. If you need idempotency, guard with a check: if (-not (Get-Command Get-MyHelper -ErrorAction SilentlyContinue)) { . "$PSScriptRoot\Helpers.ps1" }

Related Cmdlets / See Also

Wrapping Up

Dot sourcing is the simplest way to share functions across scripts without a full module. Use the dot-space-path syntax, anchor paths with $PSScriptRoot, and load common libraries in your profile for always-available utilities. When your library grows past a handful of functions, graduate it to a proper module.

Send-Item -To