class聽MyClass聽{
聽聽聽聽#聽Property:聽Holds聽name
聽聽聽聽[String]聽$Name
聽聽聽聽#聽Constructor:聽Creates聽a聽new聽MyClass聽object,聽with聽the聽specified聽name
聽聽聽聽MyClass([String]聽$NewName)聽{
聽聽聽聽#聽Set聽name聽for聽MyClass
聽聽聽聽聽聽$this.Name聽=聽$NewName
聽聽聽聽}
聽聽聽聽#聽Method:聽Method聽that聽changes聽$Name聽to聽the聽default聽name
聽聽聽聽[void]聽ChangeNameToDefault()聽{
聽聽聽聽聽聽$this.Name聽=聽"DefaultName"
聽聽聽聽}
聽聽}
[MyClass].GetType()
[PowerShell]::Create().AddScript('[MyClass]::new("ffff")').Invoke()
Class types should not leak to other runspaces.
Type was able to be created in other runspace.

Name Value
---- -----
PSVersion 6.2.0
PSEdition Core
GitCommitId 6.2.0
OS Darwin 18.2.0 Darwin Kernel Version 18.2.0: Thu Dec 20 20:46:53 PST 2018; root:xnu-4903.241.1~1/RELEASE_X86_64
Platform Unix
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0鈥
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
WSManStackVersion 3.0
This doesn't repro without _using_ the class in some way (i.e. calling [MyClass].GetType()). That part is important.
cc @daxian-dbw who wasn't able to repro this (I assume on Windows? Using PowerShell Core 6.2?)
@TylerLeonhardt been a while since I played with it, but don't new [powershell] instances execute in the current runspace unless you manually assign them a new one?
I'm pretty sure they're in a new runspace because Get-Runspace returns another runspace. Just to be sure, I tried manually creating a new runspace and the issue still repros:
class聽MyClass聽{
#聽Property:聽Holds聽name
聽聽[String]聽$Name
聽聽#聽Constructor:聽Creates聽a聽new聽MyClass聽object,聽with聽the聽specified聽name
聽聽聽MyClass([String]聽$NewName)聽{
聽聽聽#聽Set聽name聽for聽MyClass
聽聽聽聽聽聽$this.Name聽=聽$NewName
聽聽}
聽聽#聽Method:聽Method聽that聽changes聽$Name聽to聽the聽default聽name
聽聽[void]聽ChangeNameToDefault()聽{
聽聽聽聽聽聽$this.Name聽=聽"DefaultName"
聽聽}
}
$rs = [runspacefactory]::CreateRunspace()
$rs.Open()
[MyClass].GetType()
[PowerShell]::Create($rs).AddScript('[MyClass]::new("ffff")').Invoke()
Windows PowerShell 5.1 behaves the same way. A loaded type definition is available process wide unless maybe the process is using AppDomains for isolation but 5.1 doesn't appear to use AppDomains. And there is no support for AppDomains in .NET Core anyway.
@rkeithhill I'd expect the type to still be loaded, but I wouldn't expect PowerShell to resolve it since resolution is scope based:
& {
class MyClass {}
}
# Returns the above class
[AppDomain]::CurrentDomain.GetAssemblies().
Where{
[Reflection.CustomAttributeExtensions]::IsDefined(
$_,
[Management.Automation.DynamicClassImplementationAssemblyAttribute])
}.ForEach{
# The types sometimes have a distinguishing namespace
$_.Modules[0].FindTypes([Reflection.Module]::FilterTypeName, 'MyClass')
}
# Throws type not found
[MyClass]
Edit: Side note, I can't repro on 5.1 nor 6.2 on Windows. I get an Unable to find type [MyClass]. error in Streams.Errors
Also @vexx32
been a while since I played with it, but don't new [powershell] instances execute in the current runspace unless you manually assign them a new one?
Only when you pass [System.Management.Automation.RunspaceMode]::CurrentRunspace
PSReadLine plays a role in the repo. To get consistent repro on all platforms (including powershell.exe), do the following:
-noprofileclass MyClass {
# Property: Holds name
[String] $Name
# Constructor: Creates a new MyClass object, with the specified name
MyClass([String] $NewName) {
# Set name for MyClass
$this.Name = $NewName
}
# Method: Method that changes $Name to the default name
[void] ChangeNameToDefault() {
$this.Name = "DefaultName"
}
}
[MyClass].GetType()
[PowerShell]::Create().AddScript('[MyClass]::new("ffff")').Invoke()
Then you will see the Name: ffff printed out.
The moment you remove PSReadLine, this won't repro. This is because PSReadLine always parse the input before it's sent to engine to execute. The parsing involves resolving [MyClass], and put it in the type cache with the wrong TypeResolutionState.
:tada:This issue was addressed in #11273, which has now been successfully released as v7.0.0-rc.1.:tada:
Handy links:
Most helpful comment
I'm pretty sure they're in a new runspace because
Get-Runspacereturns another runspace. Just to be sure, I tried manually creating a new runspace and the issue still repros: