Reusing/Sharing of powershell remote sessions accross scripts

I have a program that generates batch files and run them

Each batch file runs a .ps1 script and this ps1 script opens a remote session to a server to run against.

My issue is that the remote server is only allowing me 3 cuncurrent sessions so, when more than 3 batch are running in the same time. Some are failing.

I didn't find any way to open a global session to the remote server and share it across the ps1 scripts or run all the ps1.scripts in the same opened powershell window instead of creating a new one each time.

PTGRPAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

chrismerrittCommented:
You can either increase the MaxShellsPerUser variable in winrm to a higher value to allow more concurrent connections, or you can look at some way of using your current sessions more intelligently.

For point 1:

winrm get winrm/config

Will display the current config

winrm set winrm/config/winrs '@{MaxShellsPerUser="10"}'

Will set the MaxShellsPerUser to 10 for example, must be done on the remote machine you are connecting to.

For Point 2:

$Session = New-PSSession -ComputerName "MachineName"

Will open a new session to a computer and store it in your $Session variable.

You can then run commands against this session by calling commands like this for example:

Invoke-Command -Session $Session -ScriptBlock {Get-Service}

However you cannot share sessions across multiple windows in PowerShell. Therefore you need to be smarter about calling your commands from within the main PowerShell window instead, or ensuring at the least that you are closing your PSSessions off properly after using them.

I.e. Remove-PSSession $Session

Maybe if we could see the code we could get a better idea about how to help.

Quite a bit on the subject here:

http://technet.microsoft.com/en-us/library/dd347653.aspx
0
PTGRPAuthor Commented:
thank you for the reply but

1. I don't have control over the remote server I am jus connecting remotely to that exchange hosted server to provision my users

2. I am already using new-PSSession and Remove-PSSession the issue is that each batch file is running separately and thus creating a new session.

I have a script that gets triggerted every time a user is added to the HR database and this scripts creates a .ps1 file and runs it. I am unable to find a way to run a .ps1 in an already opeend powershell window to be able to reusie the established session
0
chrismerrittCommented:
Why do you need to run a .ps1 script inside of a powershell window, can you not run the code in the existing powershell window?
0
What were the top attacks of Q1 2018?

The Threat Lab team analyzes data from WatchGuard’s Firebox Feed, internal and partner threat intelligence, and a research honeynet, to provide insightful analysis about the top threats on the Internet. Check out our Q1 2018 report for smart, practical security advice today!

PTGRPAuthor Commented:
this is exatcly my question how to do this !

The trigger creates a .ps1 file and runs it as powershell.com "file.ps1" which creates a new powershell isntance everytime
0
chrismerrittCommented:
I'd need to know what code you are trying to run in order to advise more to be honest, unless I know what you're trying to do it's very hard for me to say what you should do instead.
0
PTGRPAuthor Commented:
The code is very simple

$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://ps.hoster.com/powershell/ -Credential $Cred -Authentication Basic –AllowRedirection
Import-PSSession $Session

$password = $args[0] -AsSecureString
New-Mailbox -UserPrincipalName FirstLast@ourdomain.com -Alias FLast -Name FirstLast -Password $password -FirstName First -LastName Last -DisplayName "First Last"

Remove-PSSession $session

0
chrismerrittCommented:
You said:

"I have a script that gets triggerted every time a user is added to the HR database and this scripts creates a .ps1 file and runs it. I am unable to find a way to run a .ps1 in an already opeend powershell window to be able to reusie the established session"

So your script (which I assume runs PowerShell) creates a new .PS1 file with the above code and then executes that?

Can you provide the code for your executing script?
0
PTGRPAuthor Commented:
Thank you really to take a look into that, I am just running

powershell.exe filename.ps1

thta's it
0
chrismerrittCommented:
Sorry for any confusion, what i'm saying is what script are you running that calls this? what is the code for that script?
0
PTGRPAuthor Commented:
HR users a webapplication to add users, this web application is creating the user in the HR database and running a batch script.

The batch file does 2 things
1. it creates the .ps1 script I gave you above
2. runs it using this command powershell.exe filenamein1.ps1

that's it
0
chrismerrittCommented:
So whenever you add multiple users, i.e. 10 user accounts, the batch file tries to process 10 x .PS1 scripts and then hits the max connection limit and fails? would that be a fair assumption? and indeed is that the major problem you are having?

I assume when adding singular accounts the problem doesn't occur.

What schedule does this batch script run on as well?
0
PTGRPAuthor Commented:
If one HR person adds 10 users at the same time then 1 ps1 script is created for the 10 users and I have no issues with it.

However if I have registration day and I have many people adding new users only the first 3 will fire correctly and the rest will fail leading to the problem

The script runs directly on the submit not schedule
0
chrismerrittCommented:
How much control do you have over the way this works?

Could you instead of running a script on submit, update the DB with a flag to create the user and then run a scheduled task or similar to check for which users need to be added and call them all in a single script?
0
PTGRPAuthor Commented:
Well Chris I did think of this, this would solve the issue of creating the users however students password reset is also done by a portal too and they don't agree to schedule the password resets they want it in real time.

I was trying to find a way to capture an already opened powershell window (maybe using get-process) and somehow let the new ps1 script run in it and I couldn't do this
0
chrismerrittCommented:
I see, how about instead the script keeps trying to add the users until it succeeds? so perhaps make an attempt, if unsuccessful then delay for 30 secs, then try again until it gets through?

Once you close off your previous sessions it will release the session counters and let you make a new connection at that point.
0
PTGRPAuthor Commented:
That would be an idea

How can i know if the session was opened succesfully or not ?
0
chrismerrittCommented:
This function should work, checked against my local host server anyway.

It will keep running the Session connection attempt until it succeeds and then it will process the rest of the code.

Contains a 5 second delay, change it to your own value if you want :)

#Function to keep on trying to open a Session
Function Open-Session
{
	Write-Host "Attempting to Establish Session..."
	
	Do
	{
		$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://ps.hoster.com/powershell/ -Credential $Cred -Authentication Basic –AllowRedirection
		Import-PSSession $Session
		
		if ($Session)
		{
			Write-Host "Session Established"
			return $Session
		}
		else
		{
			Write-Host "Failed to Establish Session - Sleeping for 5 seconds"
			Start-Sleep 5
			Write-Host "Sleep End"
		}
	}
	While ($Session -eq $Null)
}

#Connect with Remote PowerShell
$RemoteSession = Open-Session

#Write your code here now that the session is established.

#Clear Session
[string]$SessionID = $Session | % {$_.InstanceId.guid}
$SessionID = $SessionID.Trim()

Remove-PSSession -InstanceID $SessionID

Remove-Variable -Name "SessionID"

Open in new window

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
PTGRPAuthor Commented:
Thank you so much for taking the time to do this for me


Anyway I can get the return value for the new-mailbox for example ? how can i know if it was sucecsfful or not ?

0
chrismerrittCommented:
You will need to trap the error if it occurs in your command. To put it simply I tend to use the Try Catch method like this, this is a simple example:

Try
{
	Get-Service -Name "Windows Update2" -ErrorAction "Stop"
}
Catch [Exception]
{
	Write-Host "$($_.Exception)"
}

Open in new window

0
PTGRPAuthor Commented:
Thanks a bunch
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Powershell

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.