How to Write Simple, Scalable HTML PowerShell Graphic User Interfaces for managing Rapid Recovery (3 of 3)

Part one of this blog post may be retrieved here.

Part two of this blog post may be retrieved here.

In the previous two posts we have put together a number of functions to simplify any further deployments:

  1. Use-RunAsAdmin which makes sure that the script will run in elevated mode
  2. Get-IeObject which launches an Internet Explorer Com Object (not too much to see as yet, beside an empty webpage)
  3. Check-GAC which checks if a required Office DLL is in the GAC and gives instructions as of how to obtain it. (This is an one time operation but I feel that it still needs to be handled by the script).
  4. Get-File which helps the Check-Gac function by providing a Windows Style OpenFile dialog.
  5. Create-BasicHTML which contains the HTML skeleton of the GUI
  6. Create-Button which creates a button, a checkbox (that may be shown or hidden) to modify the button’s scope and a yellow shadow that stays on while the action triggered by hitting the button is performed. At last there is a hidden field associated with the button. The value of this field changes when the button is clicked and as a result an action is triggered.
  7. Create-checkbox which does what it says – creates a checkbox and nothing more
  8. Create-textbox which creates a textbox used to collect some input data.


At the current stage the script looks like this:

For the content of the regions at this time, please check my previous posts.

Running the script, we get a first glance as of how the final product will look like:


The time has come to make this script to actually do something! As such, we need to focus on the #execute script region.

Currently, this region is quite empty… It looks like this:

Basically, it is a loop that ends only when the value of the “Exit” hidden field changes.

We want to populate this area with function that would actually do something when, for instance a button is clicked. As mentioned above, each button is associated with a hidden field which changes value if the button is clicked. This change is detected while the loop runs and as a result the appropriate action is triggered.

Since this is a repetitive action, it makes sense to write a function containing the background operations.

Basically, first thing to do is to check if the button was clicked by evaluating the value of the associated hidden field. If it was not, nothing happens. If it was, an action passed as a parameter is performed, the result is converted to HTML and returned. Before exiting, the function makes a log entry, resets the yellow button shadow and the value of the hidden field used to trigger the button action.

This function, named “execute-button” and has the following parameters:

-simplename = the name of the button

-buttontask = a string re the button action (it will be converted to a script block and executed by the function).

-resultarea  = the location where to display the result of the operation requested by ‘–buttontask

-logarea = the text of the entry for the log

-xforce = forces the execution of the button even if the associated hidden field action was not changed. This is needed for some more complicated operations that go beyond the scope of this posting.

When all is put together, the execute button function looks like this (click image to enlarge):

Please note that in the interest of simplicity, I have used another function to write to the log area. It is a very simple function. The only reason it was created was to avoid the timestamp code clutter. Please note that, since the log is hosted in a HTML textarea control, the normal LF/CR apply as opposed to the HTML break (<BR/>).

The addto-log function takes two parameters:

-logarea = the actual text and

-idtxta=the id of the textarea to add the log entry to).

The function looks as below – it is too simple to comment it.

To check if all this effort bears fruit we need to focus on what the button task should accomplish.

In our case, we need to get the content of a specified event log.

To do this, we could enter a long line of code as the ‘-buttontask’ parameter value but, as you have probably already guessed, we are going to be better off by writing a new function.

This function, called “get-mylog” takes two parameters:

-dlogname =  the name of the log (I could have used a drop down box to select from those available but this will be for some other time) and

-days = the number of days for which the events in the logs will be retrieved. I found this to be simpler and more convenient that choosing dates from date controls. There is a good time now to make use of the checkboxes allowing filtering the events as well.

The code for the function looks as below (click image to enlarge):

One more function and then we can begin to wrap up and see if everything works!

We need a function to allow saving the results to a CSV file. This function is very similar with the get-file function already discussed in the first part of this blog post. However, I decided to write it separately for clarity’s sake. Not too much to talk about it, just a regular Windows Forms SaveFileDialog with csv/wildcard filters. Here it is:

First we need to add the appropriate line of code in the Execute Script region. To simplify it, I have broken down the line based on the execute-button parameters.

The script looks now like this:

Let’s see how it works. I checked the “Export” Checkbox and selected the “information” filter.

When I hit the Get_Log button, the SaveFile Dialog opens up. Please note the yellow shadow that shows what button has been clicked (this becomes increasingly important as the complexity of the application grows and there are multiple buttons performing partially similar actions – i.e. open a SaveFileDialog before collecting some specific data).  

Once the job ends, the information is displayed in the Result pane filtered by the information type and the actions performed are logged and visible in the log area.

Unchecking all filters or checking all will yield the same result: all events are displayed.

As such, we have two more things to do so the Clear_results and Clear_Log buttons perform their actions.

These are very simple operations.

Let’s start with the clear results action. The only thing to do is to add the following execute-button function in the execute-script region:

Again, for a better understanding, the line was split by parameters.

Finally, we need a simple function to clear the events in the desired log. The function takes just one parameter which is the log name to clear. Since it is a “destructive” operation, a warning dialog has to be added.

The commented code is shown below.

Time to add a new line in the execute-script region and put everything together.

The new line, broken by parameters is shown below.

The complete script is shown below. Please note that including all the comments, empty  and broken down lines and the overhead written to run the script in admin mode and process the possibly missing Microsoft.mshtml.dll file, the whole script has only  310 lines, which is not bad at all!

Under normal circumstances, this would conclude this post. However, I have a last goodie for you! Wouldn’t it be nice to be able to build an .exe wrapper so the whole thing would run as a Windows application? It turns out that it is rather simple to do it.

Quest developped a free PowerShell editor called PowerGUI. Although the product was discontinued, it is still available for download here.

I just checked the link and it is still up. If you are not familiar with the product, PowerGUI is a pretty nifty PowerShell editor at least for PowerShell 3.0 and earlier. Anyway, the reason we are going to use it is its capability to create an .exe wrapper for scripts with just a couple of clicks!

You just need to load the script into the PowerGUI console and then choose “Compile Script” from the Tools Menu.

You may be asked to save the script before proceeding. As soon as it is done, a dialog opens up.

Make sure to uncheck the “Show PowerShell Console Window when the script is executed” checkbox.

The other defaults are just fine (although you may want to add an icon of your own and/or a password if you do something a little more complex than what we have worked together over this Blog entry). Hit OK and in a couple of seconds the exe is generated.

Double-click the exe. It runs beautifully!

This concludes the last part of the “How to Write Simple, Scalable HTML Powershell Graphic User Interfaces for managing Rapid Recovery” blog post.

I want to thank to all who gave me feedback and asked for more! Please do not hesitate to send me your feedback.

Oh, before I end this, please do not forget to read the disclaimer below:

This script is provided "as is" for the purpose of illustrating how AppAssure/RapidRecovery tasks may be performed in conjunction with Powershell. Quest AppAssure/RapidRecovery shall not be liable for any direct, indirect, incidental, consequential, or other damage alleged in connection with the furnishing or use of this script or of the principles it demonstrates.