From the archive: Toggle-CapsLock - a PowerShell cmdlet you'll probably never need!

Sometimes you need to shout things out really loud, and on the internet, the medium of choice for shouting is ALL CAPITAL LETTERS - can we enable caps lock from PowerShell?

Can haz virtual CAPS LOCK?

Inpired by this recent question on ServerFault, I've decided to write and publish my first PowerShell cmdlet (probably about time anyways).

Without too much hassle, here goes:

Function Toggle-CapsLock
{
<#
.Synopsis
    This Cmdlet simulates a CAPS LOCK keypress
.DESCRIPTION
    This Cmdlet simulates a CAPS LOCK keypress
    It also has the ability to test whether CAPS is currently active or not
.INPUTS
    Accepts a switch to either enable or disable caps lock
.OUTPUTS
    Void
.EXAMPLE
    Toggle-CapsLock -Enable
.EXAMPLE
    Toggle-CapsLock -Disable
.LINK
    http://blog.iisreset.me
.NOTES
    Author: Mathias R. Jessen, Febuary 2014. iisresetme@mrjessen.com
#>
    [CmdletBinding(DefaultParameterSetName="Toggle")]
    Param(
        [parameter(Mandatory=$false,ParameterSetName="Enable",Position=0)]
        [Switch]$Enable,

        [parameter(Mandatory=$false,ParameterSetName="Disable",Position=0)]
        [Switch]$Disable
    )
    Begin
    {
        $CapsControlDef = @"
using System.Runtime.InteropServices;

namespace IISResetMe.PshTools
{
    public static class CapsControl
    {
        const int VK_CAPS = 0x14;
        const int VK_KEYEX = 0x1;
        const int VK_KEYUP = 0x2;


        [DllImport("user32.dll")] 
        static extern void keybd_event(byte bVk, byte bScan, uint dwFlags, int dwExtraInfo); 

        [DllImport("user32.dll")] 
        static extern short GetKeyState(int nVirtKey);

        public static void Toggle() 
        {
            keybd_event(VK_CAPS, 0x3A, VK_KEYEX, 0);
            keybd_event(VK_CAPS, 0x3A, VK_KEYEX | VK_KEYUP, 0); 
        }

        public static void Enable() 
        {

            if((GetKeyState(VK_CAPS) % 2) == 0)
            {
                Toggle();
            } 
        }

        public static void Disable() 
        {

            if((GetKeyState(VK_CAPS) % 2) != 0)
            {
                Toggle();
            } 
        }

    }
} 
"@

        try
        {
            [IISResetMe.PshTools.CapsControl] | Out-Null
        }
        catch
        {
            Add-Type -TypeDefinition $CapsControlDef
        }
    }
    Process
    {
        if($PSCmdlet.ParameterSetName -eq "Toggle")
        {
            [IISResetMe.PshTools.CapsControl]::Toggle()
        }
        else
        {
            iex("[IISResetMe.PshTools.CapsControl]::$($PSCmdlet.ParameterSetName)()")
        }
    }
}

And that's it. Overall it's pretty self-explanatory, but I'll go into details about the different components of a PowerShell cmdlet in a later post... if my whimsical mind permits it.

No guarantees :-)


(This article was originally posted on Feb 6, 2014 - the author subtly acknowledges that his past self was wise not to extend any guarantees)