This behavior is surprising to me. I'm not sure if it is as intended, as neither the documentation for ScopedItemOptions nor about_Scopes seem to contemplate the behavior of AllScope variables in the context of multiple SessionStates.
$m = New-Module {}
Set-Variable v -Value 'v.1' -Option AllScope
& $m { $v }
& $m { $v = 'v.2'; $v }
$v
& {
$v = 'v.3'
}
$v
& $m { $v }
I expected that
either there really is only one $v and the output is
v.1
v.2
v.2
v.3
v.3
or, there are two $v that are really unrelated and the output is
v.1
v.2
v.1
v.3
v.2
The actual behavior seems to be consistent with two $v that are sort-of related.
v.1
v.2
v.1
v.3
v.3
> $PSVersionTable
Name Value
---- -----
PSVersion 6.0.0
PSEdition Core
GitCommitId v6.0.0
OS Microsoft Windows 6.3.9600
Platform Win32NT
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...}
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
WSManStackVersion 3.0
The expected behaviour is that an AllScope variable be the same PSVariable object in all child scopes, module or not. The current behaviour is a bug.
Ideally, the rollout of this fix would occur after Pester/Pester#1007 is fixed. I _think_ fixing this without fixing Pester/Pester#1007 would break all Pester tests involving mocks of commands whose parameters conflict with AllScope variables that are Constant or ReadOnly. Get-Module is the most obvious affected command. Currently, mocking Get-Module inside a module using Pester works because of this bug.
@BrucePay
The expected behaviour is that an
AllScopevariable be the same PSVariable object in all child scopes, module or not. The current behaviour is a bug.
Does that applied to scopes which existed before AllScope variables was created in some parent to them scope?
& {
& {
sv a 1 -Scope 1 -Option AllScope
$a = 2
gv a -Scope 1 -ValueOnly
$a
[object]::ReferenceEquals((gv a),(gv a -Scope 1))
}
& {
$a = 3
gv a -Scope 1 -ValueOnly
$a
[object]::ReferenceEquals((gv a), (gv a -Scope 1))
}
}
Current behavior is that only new created scopes inherit AllScope variable from its parent scope.
I have experienced a similar, related bug when putting the call to Invoke-Pester into a function of a psm1 module broke PSSA tests. Examples were:
$error[0] was not defined any more in the local scope (I replaced it with $_ to fix it):powershell
try
{
CmdletThatThrows-NonTerminatingError -ErrorAction stop
}
catch
{
$Error[0].FullyQualifiedErrorId | Should -Match $expectedFullyQualfiedErrorId
}
Set-Variable of a read-only automatic variable is throwing a non-terminating error. This did not work for some automatic variables such as e.g. PSVersionTable, therfore I had to change it to use global scope when setting the variable.