Tweaking your PowerShell profile - Part 2: conditionally loading modules

Introduction

In the previous post we saw how to show the progress as PowerShell loads your profile.

I spend a lot of time working with the Azure PowerShell cmdlets so I had added them to my profile. However, it turned out that they can be a little slow to load (yes, I know I’m impatient!). Since I frequently start PowerShell I wanted a way to be able to load the Azure cmdlets only when I needed them,. Since my computer isn’t yet psychic, I opted for a simple approach where I hold down the Shift key while PowerShell loads to signal that I want the Azure cmdlets loaded. The rest of the post will show how this can be achieved

The building blocks

Windows exposes a GetKeyState function that can be used to query the state of a key (e.g. whether it is currently pressed). If we were using this from C#, we would use P/Invoke via a DllImport. Since PowerShell is built on top of .NET we can take advantage of the same functionality (with a shout out for a helpful example).

Paste the following code into a PowerShell window to create the Get-KeyState function

function Get-KeyState([uint16]$keyCode)
{
$signature = '[DllImport("user32.dll")]public static extern short GetKeyState(int nVirtKey);'
$type = Add-Type -MemberDefinition $signature -Name User32 -Namespace GetKeyState -PassThru
return [bool]($type::GetKeyState($keyCode) -band 0x80)
}
$VK_SHIFT = 0x10

Now we can execute Get-KeyState $VK_SHIFT to test the current state of the Shift key. Naturally it will return false. Instead, paste the following code into a PowerShell window and try holding down the shift key and releasing it:

while($true) { Get-KeyState $VK_SHIFT; Start-Sleep -Milliseconds 500 }

Now we have the starting point for the conditional loading, the only thing that remains is to use this to test the state of the Shift key and then conditionally load the Azure module accordingly.

Show me the code

To see an example of this, check out this gist that incorporates it into a profile script. It also includes the module loading messages from the previous post to make it easy to see what is going on.