The ability to provide an InitialSessionState along with WSManConnectionInfo when creating RunspacePool.
I need this in order to share methods/code (not data) across remote sessions.
Today I pre-run every generated PowerShell.Create() session with an initialization script to define the methods, and that takes a while for every session created.
Is there a way to statically load this code on future generated sessions?
The only reference I found for the issue is this from 2014:
https://stackoverflow.com/questions/26275700/why-there-is-no-way-to-pass-initialsessionstate-for-a-remote-runspacepool#_=_
@iSazonov Am I misusing the API or is this a real gap in the existing API?
@PaulHigin Could you please comment? Is this by-design limitation?
The way PowerShell remoting handles session state configuration is through remoting endpoint configuration. You use the New-PSSessionConfigurationFile cmdlet to define the initial session state and then Register-PSSessionConfiguration to create the endpoint on the target machine. Then New-PSSession -ConfigurationName to connect to the configured endpoint. This way the initial state information is defined once on each target machine, rather than being transferred from client to target for each remote session instance.
If you want to create custom state on a per session instance basis, you currently need to do that manually by running script after connecting to the target (as you are now doing). But that is not creating an initial state, and instead is updating it after the session is created.
We can think about a new feature that passes initial state configuration data during remote session creation, but that would entail a protocol change.
that would entail a protocol change.
@jomonson It is unreal. This is a long process and it violates backward compatibility.
@PaulHigin thanks for the detailed response. Sometimes it is not possible to position a file within a remote machine. Or there is not guarantee that this file will stay. That is the main issue with the pssessionconfiguration file. Can I leverage this feature without transferring files to the remote machine? For example can I invoke an initialization script block (startup script) without passing it as a ps1 file to be held in the remote machine? I saw that I can Set-PSSessionConfiguration but it expects a file path and not a blob of text.
Well, remoting endpoints require prior access to the target machine, and you run Register-PSSessionConfiguration there. It creates a (*.pssc) configuration file in the %windir%\System32\WindowsPowerShell\v1.0\SessionConfig directory, and that needs to persist in order for the endpoint to work.
But as I mentioned, it would be possible to send the configuration data (what is now contained in the *.ppsc file) over the wire during a connection request, and so no prior access to the target is required, and no file is stored on the target.
I think this is a reasonable feature request, and I'll tag it for committee review. It is not trivial and requires a change to the protocol. Also it only affects PowerShell session configuration, and not anything related to the WinRM host (like alternate accounts such as virtual or GMSA). One thing I like about it is that it is transport agnostic and can be used for SSH based remoting as well as WinRM remoting.
Can we get an example of what the user experience is?
Something like:
$iss = [initialsessionstate]::CreateFromSessionConfigurationFile(c:\mySessionConfig.pssc)
$rs = [runspacefactory]::CreateRunspace($connectionInfo, $iss)
$rs.Open()
$ps = [powershell]::Create($rs).AddScript($script).Invoke()
Or:
$session = New-PSSession -ConfigurationFile c:\MySessionConfig.pssc
Invoke-Command -Script { ... } -cn <targetName> -ConfigurationFile c:\MySessionConfig.pssc
@jomonson saw that you were MSFT internal, and I wanted to reach out offline to understand your scenario better, but I couldn't find you. Is it possible you can explain at a higher level what you're trying to accomplish with this?
Hey @joeyaiello,
I left Microsoft not long ago, so if you can't find me it means they've done something right on that part 馃挴
I'm trying to manage remote machines via WinRM using custom PowerShell code I've written. I wish to pre-load this code to these machines so that when I connect to them (using a RunspacePool) I can immediately invoke the relevant functions.
I don't want to explicitly pass-over files (configuration files or others) that contain this code directly to these machines, because that would require me to manage and 'baby sit' these files. Moreover these files might be meddled with by other users of these machines. Lastly it's yet another footprint on the remote machines that I'd like to avoid.
Looking into @PaulHigin's example, today I need to transfer the mySessionConfig.pssc on the source machine to all other remote machines to c:\mySessionConfig.pssc, or otherwise move it directly to %windir%\System32\WindowsPowerShell\v1.0\SessionConfig but that seems like an implementation detail of PowerShell that I should not be aware of. It also might be a source of issues for when I'm dealing with varying PowerShell versions and operating systems.
Today I find myself idem-potentically redefining these functions on every connection I make to the remote machines and that decreases performance. In addition, checking whether these functions already exist is sometimes a redundant IO procedure with some latency.
I liked @PaulHigin's idea by which the InitialState information/custom code is auto-magically passed over to the remote machine and persisted to the right location, without me needing to worry about creating the file in advance in the remote machine. By the way, it seems like this feature is already working when dealing with PowerShell session in the local machine - the interface allows specifying InitialState information when not using WSManConnectionInfo.
I hoped I could explain my motivation better. If not I'm glad to talk about it more.
@PowerShell/powershell-committee reviewed this, such a change would require a protocol change and we are not contemplating any protocol changes.
Most helpful comment
Well, remoting endpoints require prior access to the target machine, and you run
Register-PSSessionConfigurationthere. It creates a (*.pssc) configuration file in the %windir%\System32\WindowsPowerShell\v1.0\SessionConfig directory, and that needs to persist in order for the endpoint to work.But as I mentioned, it would be possible to send the configuration data (what is now contained in the *.ppsc file) over the wire during a connection request, and so no prior access to the target is required, and no file is stored on the target.
I think this is a reasonable feature request, and I'll tag it for committee review. It is not trivial and requires a change to the protocol. Also it only affects PowerShell session configuration, and not anything related to the WinRM host (like alternate accounts such as virtual or GMSA). One thing I like about it is that it is transport agnostic and can be used for SSH based remoting as well as WinRM remoting.