Show-CommandGUI an enhanced Show-Command for PowerShell

After my last post (PowerShell tricks – Use Show-Command to add a simple GUI to your functions). I was thinking how one could write a function that would not have the deficiencies that Show-Command has when it comes to providing a GUI for functions. In addition to what Show-Command does I wanted a function that:

  • Considers advanced function parameters (i.e. ValidateScript, ValidatePattern, ValidateRange, ValideLength)
  • Populates the fields with the respective default values (if applicable)
  • Provides a browse for file or browse for folder option (if the parameter name contains ‘file’ or ‘folder’)
  • Provides meaningful error messages via message boxes
  • Doesn’t require the use of Invoke-Expression in order to run the parameters against the command
  • Can be customized to my own preferences

Say hello to Show-CommandGUI.

The screenshot above is produced with the following test function:

function test{
        [ValidateSet("sun", "moon", "earth")] 
        [ValidateScript({$_ -like '*test'})]
        [Parameter(Mandatory=$true, ParameterSetName='Advanced')]
        $filePath = 'c:\test.txt',
        [Parameter(Mandatory=$true, ParameterSetName='Basic')]
        $folderPath = 'c:\'
    "pattern: $pattern"
    "number: $number"
    "string: $string"
    if ($PSCmdlet.ParameterSetName -eq 'Advanced'){
        "switch: $switch"
        "filePath: $filePath"
        "choice: $choice"
        "folderPath: $folderPath"

Producing the GUI is as simple as this:

Import-Module "$PATHTOMODULE\Show-CommandGUI.psm1"
Show-CommandGUI test

The module and the test function can be downloaded via GitHub. Please let me know if you have any questions or ideas on how to improve the function.


Photo Credit: Fernando X. Sanchez via Compfight cc


PowerShell tricks – Use Show-Command to add a simple GUI to your functions

The Show-Command cmdlet has been introduced in PowerShell Version 3 and is very useful to help discovering and learning more about PowerShell cmdlets and their respective parameters (also built into the ISE as the Show-Command Add-on).:

#Discover commands by running Show-Command without parameters
#Run Show-Command for a specific cmdlet
Show-Command Get-ChildItem

Show-Command can be also utilized for your own functions in order to provide your users with a simple GUI as it builds a graphical user interface for the provided function on the fly. Show-Command displays:

  • A drop-down for parameters that use the ValidateSet option
  • A check-box for switch parameters
  • A text box for any other type of parameter
  • An asterisk behind the parameter name in case the parameter is mandatory (the mandatory parameters are also enforced by disabling the run/copy buttons until the mandatory parameter is provided)
  • Each parameter set is displayed on a separate tab

Below is an example showing the features mentioned above using the NoCommonParameter switch to hide those parameters and PassThru in combination with Invoke-Expression in order to run the function with the chosen parameters (I couldn’t get this working otherwise):

Limitations of this approach are:

  • No enforcement for any other advanced function parameter option (e.g. ValidatePattern). The error message is displayed on the command prompt after clicking Run.
  • No option to disable/change the built-in functionality (e.g. disable buttons at the bottom, change minimum height)
  • No sophisticated options for specific parameter types (e.g. browse for files)

What are the GUI options you like to you use for your functions?
Update: I’ve added a follow-up post with a new function that removes the disadvantages mentioned above

Photo Credit: Sun Spiral via Compfight cc

A nicer PromptForChoice for the PowerShell Console Host

Sometimes it’s not possible to fully automate a certain process and we need some input from the user(s) of the script in order to determine the further path of action. If this is based on a fixed set of choices the built-in PromptForChoice method can come to the rescue. Here is an example:

Running the code below in PowerShell ISE will produce the following result:

Running the same from the PowerShell console though will not look as fancy:
The reason for the difference is that the underlying PromptForChoice method on the System.Management.Automation.Host.PSHostUserInterface is declared as an abstract method. This basically means that the implementation details are up to the respective PowerShell host (as long as the method complies with the declaration).
As a result your script will not provide a consistent user experience across PowerShell hosts (e.g. ISE, Console). Because of this I wrote a little Windows.Form based helper function that provides the same features as PromptForChoice but will look the same across all PowerShell hosts:

Using Get-Choice like this:

Get-Choice "Pick Something!" (echo Option1 Option2 Option3) 2

Will look in both ISE and Console like that:

The most notable parts of the function are probably in the loop on lines 46-59. Where the buttons are created dynamically based on the options provided.:

foreach ($option in $Options){
        Set-Variable "button$index" -Value (New-Object System.Windows.Forms.Button)
        $temp = Get-Variable "button$index" -ValueOnly
        $temp.Size = New-Object System.Drawing.Size($buttonWidth,$buttonHeight)
        $temp.UseVisualStyleBackColor = $True
        $temp.Text = $option
        $buttonX = ($index + 1) * $spacing + $index * $buttonWidth
            $script:result = $this.Text; $form.Close() 
        $temp.Location = New-Object System.Drawing.Point($buttonX,$buttonY)

Similar to the way it works in PromptForChoice preceding a character from within the option values with an ampersand (e.g. Option &1) will make the button accessible via ALT-key + the letter (e.g. ALT + 1).
The function can also be found in my GitHub repo.


Photo Credit: zachstern via Compfight cc

Search file content by keyword using Everything + PowerShell + GUI

Even with Windows 10 MS still didn’t manage to include a proper in-built file search functionality. If it is about searching for files I definitely prefer the excellent Everything search engine (see also my post on a PowerShell wrapper around Everything commandline) .But quite frequently I also need to search for keywords/pattern within files. PowerShell’s Get-ChildItem and Select-String can certainly do this together:

#search through all .ps(m)1 files for instances of the word 'mySearchString'
$path = 'c:\scripts\powershell'
Get-ChildItem $path -Include ("*.ps1","*.psm1")) -Recurse |
     Select-String 'mySearchString' | select Path, Line, LineNumber

While this does the job it doesn’t follow my preferred workflow and is also not very quick when running it against a large set of files. I would prefer to have the ability to search and drill down a list of files within a Graphical User Interface just like Everything and then search through the filtered list of files using keyword(s)/pattern(s) and get back the search results within a reasonable time-frame.
Say hello to “File Searcher” (I didn’t spend any time thinking about a catchy name):
The three text boxes at the top of the UI can be used to:

  1. Search for files using Everything command-line (es.exe)
  2. Search within the list of files for content by keyword (using a replacement for Select-String more on that below)
  3. Filter the results by keywords (across all columns). This can be done against the list of files and against the list of results (Path, Line, LineNumber)

Let’s first look at two use cases.
1. Assuming we want to search for some PowerShell files starting with “Posh-” across the whole hard drive:

  • After importing the module (Import-Module $path\FileSearcher.psm1) files can be searched using the textbox at the top of the window
  • Using ‘posh-*.ps1’ and hitting Enter as the search term will get us what we want
  • On my machine this results into a quite long list. I can scroll through the list to see whether I really want to search through all those files or further drill it down either by refining the initial search or using the ‘filter results’ textbox.
  • For the example’s sake let’s assume I’d like to filter the result list to show only those entries that contain the word ‘string’ (within the full path)
  • Now I would like to search those files for instances of the word ‘select’. Entering the keyword into the 3rd text-box filters the results as I type.
  • The result is a list of ‘Path, Line, LineNumber’ results that can be further filtered by using the ‘filter results’ text-box again
  • Double-clicking one of the entries will open the file in notepad++ (of course only if this is installed) putting the cursor on the respective line. (This works only of notepad++ is not already open)

2. A second use case are situations where I want to “pre-populate” the list of files via command-line instead of using the GUI. Here is how to do that:

  • Pipe a list of files into the FileSearcher function:
    Import-Module $path\FileSearcher.psm1
    $path = 'c:\scripts\powershell'
    Get-ChildItem $path -Include ("*.ps1","*.psm1")) -Recurse | FileSearcher
  • Use the UI to further refine and/or search the list of files for contents by keyword

The content search functionality is realized through a custom cmdlet (Search-FileContent) implemented in F# based on the solution (I have only changed the original solution to accept an array of strings for the full paths) provided in this blog post. This speeds up the performance significantly as compared to Select-String through the usage of parallel asynchronous tasks.
The UI also support some options:

  • For file search (through Everything) the “no Recurse” option is applied if the first search term is a path (using the parents:DEPTH option which requires an up-to-date Everything version) e.g. the search term ‘c:\scripts .ps1’ with the option enabled would only search for .ps1 files within the c:\scripts directory.
  • The content search offers options similar to the Select-String switches to treat the keyword not as a regular expression (SimpleMatch) or/and do a case sensitive search.


  1. Everything command line version (requires the UI version to be installed,too) installed to ‘C:\Program Files*\es\es.exe’
  2. The Search-FileContent cmdlet is implemented via the SearchFileContent.dll which can be downloaded from my GitHub repository and needs to reside in the same folder as the FileSearcher.psm1 file.
  3. Because the Search-FileContent cmdlet is written in F# it requires the FSharp.Core assembly to be present which can be downloaded and installed via the following PowerShell code:
    $webclient = New-Object Net.WebClient
    $url = ''
    $webclient.DownloadFile($url, "$pwd\FSharp_Bundle.exe")
    .\FSharp_Bundle.exe /install /quiet
  4. The ability to open files from the file search content results via double-click with the cursor on the respective line requires Notepad++

The FileSearcher module itself can be also downloaded from my GitHub repository.
Please use the comment function if you have any feedback or suggestions on how to improve the tool.


Photo Credit: Robb North via Compfight cc