I'm writing CI/CD scripts in PowerShell and split larger scripts into separate .ps1 files for clarity. For example, a paths.ps1 script creates a common paths object, which I then dot-source from build.ps1:
# paths.ps1
$Paths = [pscustomobject]@{
BuildRootDir = Resolve-Path "$PSScriptRoot/.."
SrcDir = Resolve-Path "$PSScriptRoot/../src"
}
# build.ps1
. "$PSScriptRoot/paths.ps1"
$Paths.
The script runs correctly, but the editor doesn't provide autocomplete after typing $Paths.. Is there a practical workaround for getting IntelliSense to recognize objects created through dot-sourcing or imported scripts?
4 Answers
A language server can analyze PowerShell files and provide editor completion, but its support still depends on what it can infer statically. The Microsoft PowerShell extension for Visual Studio Code already provides language-server features, though runtime-created variables such as those from dot-sourced scripts may remain difficult to resolve automatically.
PowerShell completion mainly comes from the current session state or from static type inference. The easiest workaround is to dot-source paths.ps1 in the editor’s integrated PowerShell console before working on the script. Once the variable exists in that session, completion should be available.
Another option is to make paths.ps1 output the object instead of assigning it, then capture the result in the consuming script: $Paths = ./paths.ps1. However, inference may still struggle with $PSScriptRoot because it only exists at runtime, so dot-sourcing the setup script in the console is usually the most reliable approach.
Try dot-sourcing the script in the PowerShell debug terminal rather than a generic terminal. The PowerShell-aware terminal can use the variables established in that session when providing completions.
If the shared code consists mostly of functions, consider turning it into a PowerShell module. Put the functions in a .psm1 file and place the module somewhere in the module search path. Once imported, the functions behave like normal commands and generally receive much better tab completion and IntelliSense support.

Dot-sourcing the setup script in the console works well enough for my use case. Thanks for explaining why the editor can’t infer the object automatically.