Add spell checking to PowerShell ISE

4126262859_88a806a90e_m

While the PowerShell ISE is obviously for writing PowerShell code rather than text, I usually have a fair amount of it in some of my scripts due to comments or hard coded text elements. Therefore, I thought that it would be handy to have the ability to verify selected text against a spell checker.

spellcheck

I have extended my ISEUtils (It can be downloaded from my GitHub repository) module with the functionality. The spell checking works against the selected text within the ISE and can be activated by pressing F7.
The spell checking is based on the built-in ability of the WPF TextBox which automatically adds the squiggly lines for misspelled words and the spelling suggestions within the context menu. Clicking on the button “Auto Correct” will automatically correct the whole text using the first spelling suggestion (this can lead to some funny results). The spelling uses the “en-us” dictionary if you want to change this you will need to modify the code.
The “spell-checking code” is fairly simple (using ShowUI to build the GUI):

New-DockPanel {
        New-Button 'Auto-Correct (use first spelling suggestion)' -Dock Bottom -On_Click{
            $txtBox = $this.Parent.Children | where {$_.Name -eq 'txtBox'}
            $startIndex = 0
            $errorIndex = $txtBox.GetNextSpellingErrorCharacterIndex($startIndex, [System.Windows.Documents.LogicalDirection]::Forward)
            while ($errorIndex -ne -1){
                $startIndex = $errorIndex
                $error = $txtBox.GetSpellingError($errorIndex)
                $suggestion = @($error.suggestions)[0]
                if ($suggestion){
                    $error.Correct($suggestion)
                }
                $errorIndex = $txtBox.GetNextSpellingErrorCharacterIndex($startIndex, [System.Windows.Documents.LogicalDirection]::Forward)
                if ($errorIndex -eq $startIndex){
                    $errorIndex = $txtBox.Text.IndexOf(' ',$startIndex) + 1
                }
            }
        }
        New-TextBox -Language 'en-us' -Dock Top -TextWrapping Wrap -VerticalAlignment Stretch -HorizontalAlignment Stretch -Name txtBox  -FontSize 15 -AcceptsReturn -On_Loaded {                       
            $this.Text = $psise.CurrentPowerShellTab.Files.SelectedFile.Editor.SelectedText           
            $this.SpellCheck.IsEnabled = $true          
        }
} -Show

shareThoughts


Photo Credit: Will Montague via Compfight cc

Fix: Clipboard is not working + Restart-Process with PowerShell

24460391384_1668f05155_m
Sometimes it happens that the clipboard stops working. The routine of copy and paste we all rely on so many times a day suddenly refuses to do its job. The reason this happens is usually an application blocking the keyboard, making it impossible for other applications to get access to the clipboard. In order to fix this, one needs to find out which application is the culprit and either stop or restart the respective process in order to “free up” the clipboard.
I put together a small PowerShell function (Clear-Clipboard), that does just that:

clipboardBlocking

  1. It identifies the process that currently blocks the clipboard (Using GetOpenClipboardWindow and GetWindowThreadProcessId API calls)
  2. Opens a small GUI offering options to either stop or restart the process

Other than the mentioned Clear-Clipboard function. I’m also sharing Restart-Process as a separate function as it might be useful at times. Both can be downloaded from my GitHub repository.

shareThoughts


Photo Credit: Andi Campbell-Jones via Compfight cc

Fix: Chrome won’t start or taking a long time to start

25187751746_7369950f8d_m

Two simple, yet not intuitive solutions to solve two quite annoying Chrome problems (worked for me on Windows 10 and Windows 8).

1. Chrome browser refuses to launch

Solution: Reset the winsock catalog (see https://support.microsoft.com/en-us/kb/811259 and https://technet.microsoft.com/en-us/library/cc753591%28v=ws.10%29.aspx for more details).:

  1. Open an elevated command prompt (see here)
  2. Type: netsh winsock reset and hit Enter
  3. Restart your PC

2. Chrome takes a very long time to launch:

Solution: Disable hardware acceleration:

  1. Open chrome and type chrome://settings into the address bar and hit Enter
  2. Scroll down and click “Show advanced setttings…”
  3. Scroll further down and untick the box next to “Use hardware accelartion when available”

shareThoughts


Photo Credit: Dakiny via Compfight cc

Retrieve UninstallStrings to fix installer issues

24356667904_413b3b0856_m
Recently I have encountered several installer related issues on my machine. Most of them seemed to be caused by insufficient privileges.
This kind of issue can be usually fixed by running the installer “As Administrator”. In case the issue is in relation to an already installed software packet, it’s sometimes not so easy to locate the respective uninstaller/MSI packet, though. For that purpose, I’ve written a small PowerShell function that scans the registry (it turned out that if you are using PowerShell v5, there is a better way of doing this. See below for more details) (have a look here on why I didn’t want to use WMI Win32_Product instead) for the information. The function has the following features:

  • Search for software by name including wildcards (parameter DisplayName defaults to ‘*’)
  • Search through user specific (HKCU) and/or machine specific (HKLM) registry hives (parameter Hive defaults to HKLM, HKCU only accepts a combination of ‘HKCU’ and/or ‘HKLM’)
  • If a key is found matching the DisplayName. Output an object with the following properties: RegistryHive, DisplayName, UninstallString, msiGUID (if present), InstallLocation=$subKey.InstallLocation, Version (DisplayVersion)

Usage (if your PowerShell version < 5):

#search for the chrome uinstaller only in the machine wide registry hive
Get-Uninstaller *chrome* -Hive HKLM

Output:
GetUninstaller
If you happen to be on PowerShell v5 ($PSVersionTable.PSVersion.Major -eq 5) you can use the built-in Get-Package to retrieve the same information:

Armed with that information one can easily run the installer (MSI) or uninstall routine with elevated privileges in order to fix some installer related issues. For msi installer packets the following command will reinstall the respective software (see here for more details on the reinstall mode). It hopefully goes without saying, that you should only run those commands if you know what you are doing:

msiexec /i {msiGUID} REINSTALL=ALL REINSTALLMODE=omus /l*v log.txt

Below is the source of the helper function for older PowerShell version. I have also uploaded another adaption that uses the best approach depending on the PowerShell version, to my GitHub repo.

shareThoughts


Photo Credit: Chad Sparkes via Compfight cc

Use PowerShell to set Exchange Out of Office status from any PC

24549821590_a4ce2a15cd_m
I’m sure this has also happened already several times to you. You finish up your work to start into your well deserved holidays and only after you arrive at home do you realize that you forgot about to set your “Out of Office” status (considering that you actually do that). Usually, this would mean that you need to use your company device in order to connect back to work and set it up. If your company is running Exchange mail servers there is actually another option available which enables you to do the same from any PC that is connected to the Internet. The EWS Managed API is the technology that enables this.
I’ve written a module that uses the API in order to set an Out of Office message. The function has the following features:

  • Check whether the EWS Managed API is installed and offer an option to download and install in case it is not
  • Option to provide credentials (-ProvideCredentials switch) or use the current
  • A pop-up calendar to select the duration of the absence.
  • Automatic calculation of the return date based on the next business day after the duration end date
  • A custom OOTO message including start and return date (based on next business day after duration end date) and your Outlook signature (the signature is copied from your work PC ($env:APPDATE\Microsoft\Outlook\Signatures\) if available or should be within the same location as the module)
  • The function also creates an appointment in your Outlook based on the provided start and end date

Usage:

Import-Module Set-OOTO
Set-OOTO 'email@domain.com' -ExchangeVersion Exchange2007_SP1 -ProvideCredential

I’ve added my email and Exchange server version as default parameters to the function (if you are using Exchange 2007SP3 you can also need to use Exchange2007_SP1 as the value for the ExchangeVersion parameter (this took me quite a while to figure out)). Other than that you can of course modify the function with your own custom message and additional features (please share).
I’m posting the code below including helper functions to set the appointment and the calendar window. The code can also be downloaded from my GitHub repo:

shareThoughts


Photo Credit: nousku via Compfight cc