Question:
I’m having some scope issues when dot sourcing powershell scripts.
Suppose I have one script ‘A.ps1’:
1 2 3 4 5 6 7 8 |
$VERSION = "1.0" # Dot source B.ps1 . .\B.ps1 function Write-Version { Write-Host "A.ps1 version $VERSION" } Write-Version |
And a script B.ps1
1 2 3 4 |
$VERSION = "2.0" function Write-Version { Write-Host "B.ps1 version $VERSION" } Write-Version |
The output of running A.ps1 will be:
1 2 3 |
B.ps1 version 2.0 A.ps1 version 2.0 |
Why this happens is quite obvious. The $VERSION
variable from B.ps1 is put into the scope of A.ps1 and overwrites that variable. Indeed, this happens with Write-Version
as well, but here A.ps1 overwrites B’s version, but because Write-Version
is called in B.ps1 before that happens, we can still see the output of B’s Write-Version function.
The question, of course, is how to prevent this?? I’ve tried various scope options, but this doesn’t seem to work when dot-sourcing. And since there are functions in B.ps1 that I do need in A’s scope, just invoking B.ps1 is probably not an option.
Does anyone have any ideas?
Answer:
You can do it by making B.ps1 a module and renaming it to B.psm1. Add Export-ModuleMember
to make your functions available to other scripts.
This would be B.psm1:
1 2 3 4 5 6 7 8 9 |
$VERSION = "2.0" function Write-Version { Write-Host "B.ps1 version $VERSION" } Write-Version # Only items specified here will be exported. If Export-ModuleMember is not used, # ALL members (functions, variables, and aliases) will be exported. In this case # if $VERSION was exported, $VERSION will be set to "2.0" in script A.ps1 Export-ModuleMember -Function Write-Version |
And A.ps1 would be:
1 2 3 4 5 6 7 8 9 10 11 |
$VERSION = "1.0" # Import B.psm1 Import-Module .\B.psm1 function Write-Version { Write-Host "A.ps1 version $VERSION" } Write-Version # Use B.psm1's `Write-Version` function B\Write-Version |