PowerShell / WindowsCompatibility

Module that allows Windows PowerShell Modules to be used from PSCore6
Other
138 stars 33 forks source link

Add-WindowsPSModulePath is modified by background runspace #67

Open jdhitsolutions opened 5 years ago

jdhitsolutions commented 5 years ago

This is a little hard to explain and I'm not sure if this is a PowerShell Core issue or something with WindowsCompatibility. So I have some transcripts to explain. Each set of commands was done in a new pwsh session with noprofile.

First, this is what I expect would happen. The runspace I create has no effect on the parent session.

**********************
PowerShell transcript start
Start time: 20190124121905
Username: BOVINE320\Jeff
RunAs User: BOVINE320\Jeff
Configuration Name: 
Machine: BOVINE320 (Microsoft Windows NT 10.0.17763.0)
Host Application: C:\Program Files\PowerShell\6\pwsh.dll -noprofile
Process ID: 17248
PSVersion: 6.1.2
PSEdition: Core
GitCommitId: 6.1.2
OS: Microsoft Windows 10.0.17763 
Platform: Win32NT
PSCompatibleVersions: 1.0, 2.0, 3.0, 4.0, 5.0, 5.1.10032.0, 6.1.2
PSRemotingProtocolVersion: 2.3
SerializationVersion: 1.1.0.1
WSManStackVersion: 3.0
**********************
Transcript started, output file is c:\work\runa.txt
PS C:\> Get-Module

ModuleType Version    Name                                ExportedCommands
---------- -------    ----                                ----------------
Manifest   6.1.0.0    Microsoft.PowerShell.Host           {Start-Transcript, Stop-Transcript}
Manifest   6.1.0.0    Microsoft.PowerShell.Utility        {Add-Member, Add-Type, Clear-Variable, Compare-Object...}
Script     2.0.0      PSReadLine                          {Get-PSReadLineKeyHandler, Get-PSReadLineOption, Remove-PS...

PS C:\> $env:PSModulePath -split ";"
C:\Users\Jeff\Documents\PowerShell\Modules
C:\Program Files\PowerShell\Modules
c:\program files\powershell\6\Modules
C:\WINDOWS\system32\WindowsPowerShell\v1.0\Modules
PS C:\> $foo = "bar123"
PS C:\> Get-Runspace

 Id Name            ComputerName    Type          State         Availability
 -- ----            ------------    ----          -----         ------------
  1 Runspace1       localhost       Local         Opened        Busy

PS C:\> Get-PSSession
PS C:\> $newRunspace = [runspacefactory]::CreateRunspace()
PS C:\> $newRunspace.ThreadOptions = "ReuseThread"
PS C:\> $newRunspace.Open()
PS C:\> $pscmd = [PowerShell]::Create().AddScript( {
        $foo = "WTF"
    })
PS C:\> $pscmd.runspace = $newrunspace
PS C:\> $psCmd.BeginInvoke()

CompletedSynchronously IsCompleted AsyncState AsyncWaitHandle
---------------------- ----------- ---------- ---------------
                 False        True            System.Threading.ManualResetEvent

PS C:\> Get-Module

ModuleType Version    Name                                ExportedCommands
---------- -------    ----                                ----------------
Manifest   6.1.0.0    Microsoft.PowerShell.Host           {Start-Transcript, Stop-Transcript}
Manifest   6.1.0.0    Microsoft.PowerShell.Utility        {Add-Member, Add-Type, Clear-Variable, Compare-Object...}
Script     2.0.0      PSReadLine                          {Get-PSReadLineKeyHandler, Get-PSReadLineOption, Remove-PS...

PS C:\> $env:PSModulePath -split ";"
C:\Users\Jeff\Documents\PowerShell\Modules
C:\Program Files\PowerShell\Modules
c:\program files\powershell\6\Modules
C:\WINDOWS\system32\WindowsPowerShell\v1.0\Modules
PS C:\> $foo
bar123
PS C:\> Get-pssession
PS C:\> Get-Runspace

 Id Name            ComputerName    Type          State         Availability
 -- ----            ------------    ----          -----         ------------
  1 Runspace1       localhost       Local         Opened        Busy
  2 Runspace2       localhost       Local         Opened        Available

PS C:\> Get-Runspace | where-object id -gt 1 | foreach-object {$_.close();$_.dispose()}
PS C:\> Stop-Transcript
**********************
PowerShell transcript end
End time: 20190124121907
**********************

Now, I run add the Windows module paths. As you see it work. But when I create the runspace, the paths are gone.

**********************
PowerShell transcript start
Start time: 20190124121935
Username: BOVINE320\Jeff
RunAs User: BOVINE320\Jeff
Configuration Name: 
Machine: BOVINE320 (Microsoft Windows NT 10.0.17763.0)
Host Application: C:\Program Files\PowerShell\6\pwsh.dll -noprofile
Process ID: 816
PSVersion: 6.1.2
PSEdition: Core
GitCommitId: 6.1.2
OS: Microsoft Windows 10.0.17763 
Platform: Win32NT
PSCompatibleVersions: 1.0, 2.0, 3.0, 4.0, 5.0, 5.1.10032.0, 6.1.2
PSRemotingProtocolVersion: 2.3
SerializationVersion: 1.1.0.1
WSManStackVersion: 3.0
**********************
Transcript started, output file is c:\work\runb.txt
PS C:\> Get-Runspace

 Id Name            ComputerName    Type          State         Availability
 -- ----            ------------    ----          -----         ------------
  1 Runspace1       localhost       Local         Opened        Busy

PS C:\> Get-PSSession
PS C:\> Get-Module

ModuleType Version    Name                                ExportedCommands
---------- -------    ----                                ----------------
Manifest   6.1.0.0    Microsoft.PowerShell.Host           {Start-Transcript, Stop-Transcript}
Manifest   6.1.0.0    Microsoft.PowerShell.Utility        {Add-Member, Add-Type, Clear-Variable, Compare-Object...}
Script     2.0.0      PSReadLine                          {Get-PSReadLineKeyHandler, Get-PSReadLineOption, Remove-PS...

PS C:\> $env:PSModulePath -split ";"
C:\Users\Jeff\Documents\PowerShell\Modules
C:\Program Files\PowerShell\Modules
c:\program files\powershell\6\Modules
C:\WINDOWS\system32\WindowsPowerShell\v1.0\Modules
PS C:\> Add-windowspsmodulePath
PS C:\> Get-Module

ModuleType Version    Name                                ExportedCommands
---------- -------    ----                                ----------------
Manifest   6.1.0.0    Microsoft.PowerShell.Host           {Start-Transcript, Stop-Transcript}
Manifest   6.1.0.0    Microsoft.PowerShell.Utility        {Add-Member, Add-Type, Clear-Variable, Compare-Object...}
Script     2.0.0      PSReadLine                          {Get-PSReadLineKeyHandler, Get-PSReadLineOption, Remove-PS...
Script     1.0.0      WindowsCompatibility                {Add-WindowsPSModulePath, Add-WinFunction, Compare-WinModu...

PS C:\> $env:PSModulePath -split ";"
C:\Users\Jeff\Documents\PowerShell\Modules
C:\Program Files\PowerShell\Modules
c:\program files\powershell\6\Modules
C:\WINDOWS\system32\WindowsPowerShell\v1.0\Modules
C:\Users\Jeff\Documents\WindowsPowerShell\Modules
C:\Program Files\WindowsPowerShell\Modules

C:\Program Files (x86)\Microsoft SQL Server\140\Tools\PowerShell\Modules\
PS C:\> $newRunspace = [runspacefactory]::CreateRunspace()
PS C:\> $newRunspace.ThreadOptions = "ReuseThread"
PS C:\> $newRunspace.Open()
PS C:\> $pscmd = [PowerShell]::Create().AddScript( {
        $foo = "WTF"

    })
PS C:\> $pscmd.runspace = $newrunspace
PS C:\> $psCmd.BeginInvoke()

CompletedSynchronously IsCompleted AsyncState AsyncWaitHandle
---------------------- ----------- ---------- ---------------
                 False        True            System.Threading.ManualResetEvent

PS C:\> Get-Module

ModuleType Version    Name                                ExportedCommands
---------- -------    ----                                ----------------
Manifest   6.1.0.0    Microsoft.PowerShell.Host           {Start-Transcript, Stop-Transcript}
Manifest   6.1.0.0    Microsoft.PowerShell.Utility        {Add-Member, Add-Type, Clear-Variable, Compare-Object...}
Script     2.0.0      PSReadLine                          {Get-PSReadLineKeyHandler, Get-PSReadLineOption, Remove-PS...
Script     1.0.0      WindowsCompatibility                {Add-WindowsPSModulePath, Add-WinFunction, Compare-WinModu...

PS C:\> $env:PSModulePath -split ";"
C:\Users\Jeff\Documents\PowerShell\Modules
C:\Program Files\PowerShell\Modules
c:\program files\powershell\6\Modules
C:\WINDOWS\system32\WindowsPowerShell\v1.0\Modules
PS C:\> Get-pssession
PS C:\> Get-Runspace

 Id Name            ComputerName    Type          State         Availability
 -- ----            ------------    ----          -----         ------------
  1 Runspace1       localhost       Local         Opened        Busy
  2 Runspace2       localhost       Local         Opened        Available

PS C:\> Get-Runspace | where-object id -gt 1 | foreach-object {$_.close(); $_.dispose()}
PS C:\> Stop-Transcript
**********************
PowerShell transcript end
End time: 20190124121936
**********************

Finally, I didn't do anything in the parent session. But the background runspace runs the Add-WindowsPSModulePath command and it affects the parent session! Unless there is something about runspaces that I'm overlooking, this doesn't look like proper behavior. I would expect the runspace I create to be distinct from the parent.