‘Overriding’ PowerShell Command functionality to provide custom functionality – Sort of!

October 17, 2020 at 4:44 pm Leave a comment

The scenario:

I have a PowerShell command that wraps an Exif tool (ExifTool by Phil Harvey ) that uses the Write-Progress command as it takes a long time to run (about 2.5 seconds per image file and I have 1000s) as shown below.

The problem:

I want to use the command in a GUI application written using PowerShell Studio and the Write-Progress command does not work for me in this context.

The solution:

Override the functionality that shows the progress by displaying a message in PowerShell Studio GUI’s status bar: 

The method:

One of the benefits of PowerShell is that everything is an object, that includes code.  You can create a variable of type ScriptBlock to store the code and then execute it when needed.  In the Get-CCMetaData command I have a switch to indicate that I want the progress to be displayed.  The code to do this is:

if ($ShowProgress)
{
 Invoke-Command -ScriptBlock $ProgressScript
}

ProgressScript is a parameter for the command.  The default value for it is:

[ScriptBlock]$ProgressScript = {Write-Progress -Activity   $Global:progressActivity -Status $Global:progressStatus -PercentComplete (100*$Global:progressIndex/$Global:progressCount)}

I found that I need to declare the variables at a Global: scope to be able to provide access to the various script scopes. 

In my GUI application I have a status bar to enable information to be displayed to the user.  In the GUI application I call Get-CCMetaData with a new ProgressScript block:

Get-CCMetaData -IncludeExifData -ProgressScript ({ Set-StatusMessage -Message ("{0}: {1} ({2:N2}%)" -f $Global:progressActivity, $Global:progressStatus, (100 * $Global:progressIndex/$Global:progressCount))}) -ShowProgress

Because I am running this code block in the scope of the GUI application it has access to the GUI components such as the Set-StatusMessage command that writes to the status bar.

This means that rather than using a Progress bar, I see the progress displayed as a message telling me what file I am processing and how far through the processing I am as shown above.

I appreciate that I am not truly overriding a command’s functionality.  I am writing the original command to support the injecting of functionality.  Rather than embedding the code in the command I provide it as a ScriptBlock as the default value for a parameter.  The critical part is to make the information needed to indicate progress as known variables.  I set the variables at the Global scope so other ScriptBlocks can access them.  This approach does require a greater knowledge of the internals of the command that would normally be available.  I have added information into the comment based help to support this:

.PARAMETER ProgressScript
	This is the ScriptBlock that will be executed when the -ShowProgress switch is set.
    The default ScriptBlock uses the Write-Progress command.  There are several variables
    that are prepared and controlled to enable custom code to display progress.
    The Variables are:
        [int]$Global:progressCount: The number of files to process.
        [int]$Global:progressIndex: The index for the current file
            being processed.
        [String]$Global:progressStatus: The name of the file currently being processed.
        [String]$Global:progressActivity: The text "Processing"

I have also added an example demonstrating a way to use this to simply write the percentage complete on the console line rather than the progress bar:

.EXAMPLE
Get-CCMetaData -Path (Get-ChildItem D:\PhotoAlbum\Europe2013*.JPG) -ProgressScript {Write-Host ("r{0:N2}%" -f (100*$Global:progressIndex/$Global:progressCount)) -NoNewline} -ShowProgress
NOTE: This does not work properly with the console in PowerShell_ISE as it does not process the `r as a carriage return properly.

Entry filed under: Uncategorized. Tags: , , .

How to write a GUI Utility in PowerShell Problems with the Windows Forms WebBrowser Control and a simple way to fix it!

Leave a comment

Trackback this post  |  Subscribe to the comments via RSS Feed


Calendar

October 2020
M T W T F S S
 1234
567891011
12131415161718
19202122232425
262728293031  

Most Recent Posts