Slow tab expansion in Ops Mgr Powershell V2 console

Slow tab expansion in Ops Mgr Powershell V2 console

  • Comments 3
  • Likes

I am a big Powershell fan, and I use the Powershell console regularly.  Depending on what I’m taking care of at the time, I might be using the plain vanilla console or I might be using the Operations Manager snapin to work with the latest builds of our product.  In both contexts, I find that a tab expansion feature makes my life a lot easier.  Powershell V1 had tab expansion support, and with Powershell V2 the tabbing capabilities have been greatly enhanced.

One bad thing I found with V2 tab expansion is that it is SLOOOW to autocomplete cmdlet names when using the Operations Manager snapin.   Typing something like “Get-Aler[TAB]” or even a standard cmdlet like “Select-Stri[TAB]” would sometimes hang your console for minutes.  This came up on the SCOM newsgroup recently, so it is clearly a problem for a fair number of folks.

So what’s the root cause of this?

In certain cases, when you try to tab expand, Powershell attempts to autocomplete to the name of an object in the current prompt location.  For example, if navigate to C:\Windows\System32 and type “user32[TAB]”, Powershell autocompletes to “.\user32.dll” as expected.  This isn’t anything new for cmd.exe users, but what’s cool is that this behavior can be enabled by any Powershell provider, so it isn’t limited to the file system.  Try moving to HKLM:\SOFTWARE, typing “microso[TAB]”, and the Powershell Registry Provider supplies the information which allows this to autocomplete out to “.\Microsoft”.  Very smooth, consistent experience.

Everything works really fast for providers like the file system and the registry, but things can sometimes take (much) longer with the Operations Manger provider.  To enable tab expanding the names of Groups and Monitoring Objects in the Ops Mgr provider, behind the scenes a few queries need to be sent all the way to the ops DB, results collected, and .NET objects built and sent back over the wire to your session.  This is what’s bogging down your prompt, especially if you are on a remote machine.

The fix is to tweak the TabExpansion function in V2 so that it doesn’t try to autocomplete child objects if using the Ops Mgr provider.  This can be done via the below script.  Paste this into your console session, or better yet add it to your profile, and tab expansion for Ops Mgr cmdlets will work much more quickly.

$tabExpand = (get-item function:\tabexpansion).Definition
if($tabExpand -match 'try {Resolve-Path.{49}(?=;)')
{
   $tabExpand = $tabExpand.Replace($matches[0], "if((get-location).Provider.Name -ne 'OperationsManagerMonitoring'){ $($matches[0]) }" )
   invoke-expression "function TabExpansion{$tabExpand}"
}

Note this only works for Powershell V2, and only if you have not already modified that line of the TabExpansion function.  In Powershell V1 more of the tab completion is handled in the engine so unfortunately a similar speedup is not possible in this case.

Trying it out:

PS># How long does it take to tab expand "get-manage[TAB]"
PS># before...
PS>measure-command {TabExpansion 'get-manage' 'get-manage' } | select TotalSeconds


TotalSeconds      : 9.6371766

PS># after...
PS>measure-command {TabExpansion 'get-manage' 'get-manage' } | select TotalSeconds


TotalSeconds      : 0.0091002

 

I’ll take a 1,000x speedup any day!

-Lincoln Atkinson

Your comment has been posted.   Close
Thank you, your comment requires moderation so it may take a while to appear.   Close
Leave a Comment
  • I am running Powershell v1, and had this issue with delayed tab expansion.  I added the script above to my profile, and no more tab expansion delays.  So this apparently affects both PS v1 and v2.

  • This affects both v2 and v1 - maybe it is just even slowER on v2?

    The fact is that, as Lincoln already explained, the OpsMgr provider really is an abstraction layer on top of the SDK service... which in turn is an abstraction layer on top of a database... so it is bound to be much slower than any other provider working in memory, or on the filesystem, or the registry... all of those PSDrives are obviously and naturally faster.

    On an unrelated note, that is also why, even tho powershell syntax is sweet, for massive extractions of data that we do to prioritize tuning, such as getting the "alerts per day" or "noisy state changes" or discoveries... all that kind of stuff is WAY faster if done against SQL directly.... and that's why the OpsMgr community comes out with tons of queries to do certain things/analysis faster.

  • Bloody marvelous.

    From 84sec down to 0.006