Using Drag and Drop in PowerShell GUIs

Drag and drop is a wonderful facility that most of us will use every day without even thinking about it. This article shows how it can be implemented in PowerShell GUI applications.

For this particular script, we’ll implement drag and drop functionality to allow us to drag a file from explorer to a textbox in we’ve created. When the drag and drop operation is complete, the textbox will then show the path to the file.

You can find a copy of the PowerShell Studio form and exported PowerShell code at the PowerShell.Amsterdam repository.

Here is what we our application will do once we have completed it:

To achieve our objective, we need to make use of two events, DragOver, and DragDrop.

DragOver occurs when the mouse is over the control on which we wish to ‘drop’ our object. We’ll typically just use this for changing our pointer to show a move or copy operation is in operation.

DragDrop occurs once the actual operation is finished. That is, the object has been dragged into the form and over the control, and the mouse button released.

To implement this in our application, carry out the following:

  • Create a form
  • Create a Textbox on the form
  • Set the following properties for the Textbox
    • Name : txtDragandDrop
    • Label : Contents dragged:
    • AllowDrop : true

1 - form design and properties

We now define the events that will be processed, and their handlers.

  • DragDrop : txtDragandDrop_DragDrop
  • DragOver : txtDragandDrop_DragOver

2 - form design and events

For the event handler code, use the following :

    #Event Argument: $_ = [System.Windows.Forms.DragEventArgs]
    if ($_.Data.GetDataPresent([Windows.Forms.DataFormats]::FileDrop))
        $_.Effect = 'Copy'
        $_.Effect = 'None'

#Event Argument: $_ = [System.Windows.Forms.DragEventArgs]
    [string[]] $files = [string[]]$_.Data.GetData([Windows.Forms.DataFormats]::FileDrop)
    if ($files)
        $txtDragandDrop.Text = $files[0]

If you are developing this application in PowerShell Studio, you will need to first export the code, either to a standalone EXE, or .PS1 file.

  • Run the application from either of the above.
  • Drag a file of you choice from explorer to the textbox.

The textbox will be populated with the filepath of the file that has been dragged and dropped over it.

4 - running

Thanks for reading!



Asynchronously Save Images in the Clipboard to File

PowerShell v5.0 introduces us with two cmdlets, Get-Clipboard and Set-Clipboard which, just as their names suggest, allow us to obtain and set the contents of the clipboard. What’s not immediately apparent though is that these cmdlets can process more than just text in the clipboard.

In this blog, we’ll focus on using Get-Clipboard, and create a script which is used in combination with Register-EvengineEvent to save an image to file any time that one is detected in the clipboard during the current session. A repo containing the script is available at GitHub

Get-Clipboard supports the processing of several types of data that is in the clipboard, one of which is that of an image type. Examples of these would be print screens or copying an image created in Paint into the clipboard.

When an image is in the clipboard, and we use Get-Clipboard -Format Image, an object of Bitmap type (inherited from System.Drawing.Image) is returned. One of the methods this class provides is Save. Save has several overloads, one of which writes to a file and a variety of formats of your choice.

The script below requires use of the ISE, and uses Register-EngineEvent to register a scriptblock, which runs when a PowerShell.OnIdle event is raised. In the scriptblock, we check to see if there is any content in the clipboard of image type. If there is, we take the details of the current file open in ISE the editor, and use it to generate a unique filename. Then, the content of the clipboard is saved to this filename using the method mentioned above. Finally, we clear the clipboard to ensure that there we don’t end up in a continuous looping operation.

Register-EngineEvent -SourceIdentifier PowerShell.OnIdle -Action {
    $content = Get-Clipboard -Format Image
    If ($content) 
        $path = $psISE.CurrentFile.FullPath | Split-Path
        $filename = "$path\ImageCap - " + (Get-date -Format 'hh-mm-ss') + '.png'
        Set-Clipboard -Value $Null

Thanks for reading!



Automatic Parameter Splatting ISE Add-On

Here’s some code I put together which converts parameters in a command to a splatted variant of them. There’s definately room for improvement with the code (it can struggles with some sequences of parameters), so any contributions or ideas would be great for this. It’s posted in my GitHub area.

The function below parses the selected text and attempts to split them into separate chunks of parameters, which are processed and then concatenated into a single string. Once complete, the existing parameters are removed from the command and replaced with the splat, and the hash table placed on the line above.

function ConvertTo-Splat

        [Parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true)] [string] $InputObject

    If (!$InputObject) 
        $InputObject = $psISE.CurrentFile.Editor.SelectedText
    $tokens = $null
    $errors = $null
    $ParsedInput = [System.Management.Automation.Language.Parser]::ParseInput($InputObject,[ref]$tokens,[ref]$errors)
    $results = $ParsedInput.FindAll({
            $args[0] -is [System.Management.Automation.Language.CommandElementAst]
    $splatstring = "`r`n`$paramblock = @{`r`n"
    For ($i = 0;$i -lt ($results.count -1);$i = $i+2) 
        $paramName = ($results[$i].Extent) -replace '-', ''
        $firstextent = $results[$i].Extent.Text[0]
        $secondextent = $results[$i+1].Extent.Text[0]
        If($firstextent -eq $secondextent) 
            $value = '$true'
            $i = $i - 1
            $value = $results[$i+1].Extent
            If ($value -notlike '*$*') 
                $value = "`"$value`""
        $splatstring += "$paramName = $value`r`n"
    $splatstring += "}`r`n`r`n"
    $currentLine = $psISE.CurrentFile.Editor.CaretLine

Run the function to store it memory. Now, in order for us to be able to call the function either from a menu or keyboard option in the ISE, run the following code. :

$psISE.CurrentPowerShellTab.AddOnsMenu.Submenus.Add('Get Splat', { 
        $text = $psISE.CurrentFile.Editor.SelectedText
        ConvertTo-Splat -InputObject $text
}, 'ALT+T')

With this done, all that’s required is to :

  • Select the parameters you wish splatted in the command
  •  Either
    • Click Add-ons in the menu bar
    • Click Get Splat
  •  Or
    • Press ALT + T
Select the parameters

Selection of the parameters and splatting option

  • View the results
The result of the autosplat

The results of the autosplat

Here’s a video of it in action: