简体   繁体   中英

Optimizing PowerShell module imports

I currently have a PowerShell script that is used for complex automated Exchange mailbox management. At times, the script will be running 20-40 instances simultaneously. The body of the script itself doesn't take much time to run; however, the script requires the ActiveDirectory module, the ServerManager module, and the Exchange 2010 PS-snapin. Loading these modules and snapins takes a few seconds when only 1 instance of the script is running. This is of course compounded once there are multiple instances of the script running. This ends up heading the box towards extremely high resource usage as it tries to load these modules 20-40 times simultaneously.

The question is this:

Is there someway to either keep the 3 required modules loaded into memory, so to speak, or is there some other way to optimize this that anyone can think of that will not require the loading of these 3 modules each time a new instance of the PowerShell script is called up?

Here is the basics of the script simplified (without: function bodies, if statements, error handling) - Let me know if you need any section added

CODE SNIPPIT:

param($ARG1,$ARG2,$ARG3) # Grab arguments from command line

# Load Modules
Import-Module ActiveDirectory
Import-Module ServerManager
Add-pssnapin Microsoft.Exchange.Management.PowerShell.E2010

# Pass Arguments to Variables
$username = $ARG1

# Create Functions
function checkValidADUser {}
function checkOldMailbox {}
function chooseMailstore {}
function createMailbox {}

# Run Functions
checkValidADUser $username
checkOldMailbox $username
chooseMailstore $username
createMailbox $username $mailstore

You can try and load just the cmdlets you need from each module. With regards to the AD module you can speed up its loading by disabling the loading of the default AD drive. Some AD operations are also available via the Exchange commands, maybe you can skip the AD module. By the way, loading the E2010 snap-in is not supported.

$env:ADPS_LoadDefaultDrive = 0
Import-Module ActiveDirectory -Cmdlet Get-ADUser,Set-ADUser
Import-Module ServerManager ...
Add-pssnapin Microsoft.Exchange.Management.PowerShell.E2010

You might take a look at PoshRSJob https://github.com/proxb/PoshRSJob

The function

Start-RSJob

has the param

-ModulesToImport

which will load the modules only once

Perhaps a bit late, but: What might also help with increasing efficiency is using: http://windowsitpro.com/blog/multithreading-multitasking-powershell

Then run your script multiple times in that runspace.

Are all these scripts started from the same console session?

If so, I'd just load them up in the console and then run the script. This way, you have the modules loaded in the memory of the current runspace and accessible to all Scripts within that session.

PS C:\scripts> ipmo -Name .\tempmodule.psm1 -Global
PS C:\scripts> .\temp.ps1
Hello, World
PS C:\scripts> 

So, in the above snippet, I put a Write-Hello function that just writes "Hello, world" to console. In the first line, I loaded up the module in global scope and then called the script that was calling Write-Hello.

How much are you using that AD module in script? If you're just doing an account validation you may be able to change that to using adsi and not have to load that module at all.

I don't know if it will help with the resource usage, but it might speed the load times if you add that Exchange management snapin dll to your GAC.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM