Avoiding Jitter: Jumpstarting the Exchange shell

Published Aug 01 2008 01:20 PM 4,878 Views

A little trick from Jeffrey Snover over on PowerShell team blog: Speeding Up PowerShell Startup. Running the script mentioned by Jeffrey speeds up PowerShell startup times. Yes, hard to believe at first, but after having run this on a few servers, as Jeffrey says - the reaction is "Wow!"

  1. Paste the following in notepad and save it as Update-Gac.ps1 (or whatever you want to call it):

    Set-Alias ngen @(
    dir (join-path ${env:\windir} "Microsoft.NET\Framework64") ngen.exe -recurse |
    sort -descending lastwritetime
    [appdomain]::currentdomain.getassemblies() | %{ngen $_.location}

    Note: On x86 systems; replace Framework64 in the second line of this script with Framework.

  2. [Optional] Close all open windows
  3. [Optional] Start the Exchange Management Shell and note the time it takes to start up
  4. Run the script: .\Update-Gac.ps1 (or whatever you saved it as)
  5. Quit all open windows, start the Shell. Notice the difference?

As Jeffrey says in his blog post, the PowerShell team had a problem in Windows PowerShell v1, that caused the binaries not to be NGENed.

What's NGEN?

Managed code exists in Common Intermediate Language (CIL). The Just In Time (JIT) compiler takes that and converts it into native code for a particular processor/platform - a process also referred to as "jitter". If you don't want this translation to happen at runtime, you can use NGEN.exe - the Native Image Generator - to convert managed code from the CIL to native code. Native code does not need to be compiled at run time, and thereby avoids jitter.

So how does speeding up PowerShell help Exchange?

The Shell is built on Windows PowerShell technology, and under the hood, the Exchange Management Console also executes PowerShell cmdlets. If you're running Exchange Server 2007 on Windows Server 2003, you're likely to see performance gains in shell start-up times after running this script. On one of my Exchange 2007 servers, EMS now starts up in as little as 2-3 seconds. Disclaimer: Your mileage may vary.

Feel free to leave feedback about results you're seeing with this.

Bharat Suneja

Not applicable
Nice, from 40-50 odd seconds (cold start) to 17-20 seconds.
Not applicable
Definitely an improvement on my servers, thanks for the tip!

But what I'm really looking for is some major enhancements to the management console interface. Perhaps a sneak peak of what's to come with SP2? :)
Not applicable
Cool trick Bharat! I am going to try that on my Exchange servers to see.
BTW, where is my book? ;)
Not applicable
dude, that's cool.  definitely sped things up for my home test environment running on a mac mini.  every second counts, and I counted from 12 secs with jitter to 4 without.
Not applicable
From 30 seconds to less than 5. Great, but why isn't this run as part of the setup process? And why is the code not native in the first place if pretty much every Exchange server in existence is x64/x86...?
Not applicable
You mention Windows 2003.  Is this also applicable on Windows 2008, or is it builtin or something?
Not applicable
I get a lot of errors about not being able to locate Exchange related assemblies - mainly because it's looking for things that are not filenames. Running this under a standard powershell session on the other hand, does wonders.

We've had this script in our script repository for a good while now, and it's semi-standard practice to run it during the build of a new system.

@Kelvin: As I understand it, it's a 'bug' in the way powershell is installed that causes this process to not get run when it normally would. I believe it's fixed in v2.
Not applicable
Ran as instructed but no real improvement.  But then again my shells were already opening in 3-5 seconds.
Not applicable
Ran the script and wow! PS load times went from 30-40 seconds to less than 5 seconds.
Not applicable
Can someone confirm that applying this wont cause problems when we come to apply exchange patchesservice packspowershell updates? Will the newer assemblies that come along with any patches "overwrite" the ones that have been etched into the gac without errors and calls to PSS?
Not applicable
@Kelvin: As stated in Jeffrey's post, it's a PowerShell v1.0 issue, corrected in PS v2.0.
(Note, Exchange Server 2007 requires PS v1.0.)

@Mark: This simply performs the task of compiling to native code in advance, rather than at run time. You should not have issues with patches as a result of this.
Not applicable
Are you guys running this script in the EMS or just standard PowerShell?

If you run this script in EMS, you get heaps of errors on 'assemblies unable to load' and 'file not found' errors. If you run this in standard PowerShell, you don't get any errors, and the script finishes in a few seconds.

Either way, the EMS and EMC startup times have not improved for me. It's still 40-50sec slow. Am I somehow screwing up in executing the script?!
Not applicable
hi Bharat..is there also a way to "undo" this change for powershell once this has been done?
Not applicable
Fantastic!  Speed up several servers from 30-45 seconds to less than 5!  As Steve said above, run the script from the standard PowerShell prompt to avoid the errors.
Not applicable
@Steve: The errors can be safely ignored.

@Satguru: Investigating if there's a way to "undo" - although I haven't come across a situation where this would be required. Will post update in these comments if I have something to report. :)
Not applicable
It took me at first 10 seconds to start, now 5. Not a really important improvement, but oh well, it saves me some lifetime in total over a year :)
Thank you for the script.
Not applicable
this seems to speed up DPM 2007 mgmt shell also. cool.
Not applicable
Not applicable
nice.... what's the code to disable?
Not applicable
Version history
Last update:
‎Aug 01 2008 01:20 PM
Updated by: