user3726368
user3726368

Reputation: 31

Powershell - how to keep imported modules loaded across sessions

I have a bunch of different scripts using a common Powershell library (mix of custom PS functions and c# classes). The scripts are executed automatically at a regular intervals. When each script is loading it is using quite a bit of CPU to import the custom modules. When all scripts fire up at once a server's CPU runs at 100%... Is there a way to import-modules only once? In this scenario all scripts are executed by a Windows service.

Upvotes: 3

Views: 2293

Answers (2)

StephenP
StephenP

Reputation: 4081

You could also load the module once into a runspacepool and pass the pool around to multiple instances of powershell. For more details see the InitialSessionState and RunspacePool classes. Sample:

#create a default sessionstate
$iss = [System.Management.Automation.Runspaces.InitialSessionState]::CreateDefault()
#create a runspace pool with 10 threads and the initialsessionstate we created, adjust as needed
$pool = [System.Management.Automation.Runspaces.RunspaceFactory]::CreateRunspacePool(1, 10, $iss, $Host)
#Import the module - This method takes a string array if you need multiple modules
#The ImportPSModulesFromPath method may be more appropriate depending on your situation
$pool.InitialSessionState.ImportPSModule("NameOfYourModule")
#the module(s) will be loaded once when the runspacepool is loaded
$pool.Open()
#create a powershell instance
$ps= [System.Management.Automation.PowerShell]::Create()
#Add a scriptblock - See http://msdn.microsoft.com/en-us/library/system.management.automation.powershell_members%28v=vs.85%29.aspx
# for other methods for parameters,arguments etc.
$ps.AddScript({SomeScriptBlockThatRequiresYourModule})
#assign the runspacepool
$ps.RunspacePool = $pool
#begin an asynchronous invoke - See http://msdn.microsoft.com/en-us/library/system.management.automation.powershell_members%28v=vs.85%29.aspx
$iar = $ps.BeginInvoke()
#wait for script to complete - you should probably implement a timeout here as well
do{Start-Sleep -Milliseconds 250}while(-not $iar.IsCompleted)
#get results
$ps.EndInvoke($iar)

Upvotes: 3

mjolinor
mjolinor

Reputation: 68243

If it's running at fairly short intervals, you'd be much better off to load it up once, leave it resident, and put it into a sleep/process/sleep loop.

Upvotes: 0

Related Questions