My overall goal is to initialize a powershell session once, invoke some commands over time and finally close the session. I need to call powershell via winrm. Since I'm developing a Java application, I use winrm4j to invoke shell commands via winrm.
The motivation behind keeping the ps session open is that I am accessing Exchange Online via Connect-ExchangeOnline
cmdlet. Unfortunately, this is taking about 10 seconds and to save time I would like to re-use the ps session for several commands like Get-Mailbox
etc instead of connecting to Exchange Online every time I invoke an Exchange cmdlet.
This is my pseudo-powershell code I am executing. For now, I am running against my local machine:
$s = New-PSSession -Name mysession -ComputerName . -Authentication Basic -Credential ...
Invoke-Command -Session $s -ScriptBlock { <# here comes Exchange online initialization #> }
Disconnect-PSSession -Session $s
$rs = Get-PSSession -Name mysession -ComputerName . -Authentication Basic -Credential ...
Connect-PSSession -Session $s
Enter-PSSession -Session $s
<# run the actual Exchange cmdlet #>
Exit-PSSession
Disconnect-PSSession -Session $s
$rs = Get-PSSession -Name mysession -ComputerName . -Authentication Basic -Credential ...
Remove-PSSession -Session $rs
When I manually do this, I can run a Get-Mailbox
and get a proper result. However, when I run it programmatically, it doesn't work. An error is returned that Get-Mailbox
couldn't be found as cmdlet. And also other variables from the initialization or not available.
What makes the difference here via winrm?
As Mathias pointed out in the comments, the solution is to use Invoke-Command
instead of Enter-PSSession
as it is for interactive session only. Unfortunately, there is no error message or similar when calling Enter-PSSession
via winrm programmatically.