The GUI Designer

PowerShell Studio fully supports the creation of GUI scripts based on Windows Forms technology.

It includes a number of predefined forms to get you started or you can start with a blank form and build everything up from scratch.

Designer Basics

The main editor screen for GUI scripts is the Forms Designer. Open PowerShell Studio 2015 and click on New, New Form, to open the main editor screen:

Designer Panes

Toolbox Pane

The Toolbox pane contains two tabs:

  1. Controls
    These are all of the GUI controls you can add to your form.
  2. Control Sets
    These are the custom controls that you can drag and drop from the Toolbox Panel into the designer like any other ordinary form control. They are made up of either single or multiple controls with predefined property values, event handlers, and functions.

Property Pane

The Property Pane allows you to edit the properties of the currently selected control. Each property has an associated editor to help guide you in choosing the correct value. The Properties Pane also displays the events that a control can respond to, and allows you to connect an event to code.


Adding Controls to the Form

To add a control to a form, simply open the toolbox and double click it in the Controls or Control Sets pane OR drag and drop it onto the form.

This screenshot shows a button control about to be dropped on to an empty form:

Manipulating Controls

The edit section of the ribbon bar contains a number of useful commands for working with controls.

These include:

Using Spacing

Equalize Vertical Space - Makes the vertical distances between the selected controls equal.


Equalize Horizontal Space - Makes the horizontal distances between the selected controls equal.


Using Tab Order

The Tab Order button is a toggle. That means that one click turns it on and another turns it off. In order to display the tab order of the form items, simply click the Tab Order button and each element on the form will show its tab order on the left.

Notice the tab order itself is a zero-based array. So zero is the first tab, one is the second tab, and so on and so forth. To change the tab order simply click on one of the elements until the number you want appears. You don't have to click on the tab order number itself, just clicking anywhere on the element will suffice. Clicking on the element simply cycles through the available tab orders. As you click on the element, the number will increase. And once you reach the end of the available tab orders it will start back at zero.

In the above screenshot the tab order is button1, button2, dropdown.

In the below screenshot, however, the tab order has been changed to button1, dropdown, button2.

Preview GUI

The Preview GUI button allows you to preview the way a form will appear at run time, without executing any of your code. When a form is in preview mode none of your controls will work, however, you can use the minimize and maximize buttons and resize the form to make sure it behaves as expected. When you are finished, close the form to go back to the designer.

Follow these steps to use Preview GUI:

  1. Click the Preview GUI button or press F4.
  2. The Save As dialog appears. Enter a name for the file you want to save.
  3. The form is displayed.

Adding Events

The simplest way to connect a control event to your code, is to use the Add Events dialog. Right click on the control and choose Add Events, or press Ctrl+E.

This will prompt the following pop-up:

Now you can select the events you want to use in your script. PowerShell Studio will write the required code and indicate where you need to add your own code.

Event handlers can also be created using the properties panel. To do this, first select the control in the designer and access the properties panel. Then click on the lightning bolt button to display the events that belong to the control. The screenshot below shows the events for a form. The load event has been connected to a handler called form1_Load.

To handle another event, simply double click in the blank cell next to the event. PowerShell Studio will create an event handler named $<object name>_<event name>.

For example, double clicking in the blank cell next to FormClosing results in the following code being generated:

If you want to specify the name of the event handler you can type its name rather than double clicking in the blank cell. PowerShell Studio will use the name you type to generate the event handler.

Form Templates

A form template is a pre-created form containing controls and script code. Templates help you create GUI scripts quickly by doing much of the layout and code writing for you.

Using Templates

To create a GUI based script, choose New Form from the New button on the Quick Access menu.

You may also choose New Form from the File menu.

Either method will display the template selector:

As you click on a template a small preview is displayed on the left. You will notice the preview image changes with the Grid Search Template above. Press Select to create the form and associated scripts.

Creating Templates

If the predefined templates do not meet your needs, you can create your own. There are two distinct types of templates:

  1. Form templates
    A form template can be based on any existing form. It is a general purpose template.
  2. Grid templates
    Grid templates can only be created from an existing form that contains a DataGridView control. These templates are designed to be used in conjunction with the Object Browser to rapidly create forms that retrieve database records or WMI objects, and display them in a grid.

To get started, create a new form and configure it as required; including event handlers and any other code.

Save your work and then go to the File menu and choose Create Template. NOTE: This functionality used to be on the Export tab of the ribbon.

You can also click on the Create Form Template button on the Templates menu of the Designer ribbon.

Next you are presented with the Create Form Template dialog:

Now fill in the form properties:

Fill in the form and press Save. Your new template will now be shown whenever you create a new form, just like the standard templates.

Working with Grid Templates

If you right click on a database table or WMI object in the Object Browser, the following menu appears:

The Generate Query Form… option will display a list of grid templates, that include code, to retrieve objects and display them in a grid. In order to allow the code generator to reuse a template for different kinds of objects, placeholders are included in the template. These placeholders get replaced with object specific code when the template is used.

There are four placeholders:

  1. %GridFunction%
    This placeholder is replaced by a data retrieval function that either retrieves records from a database and stores them in a ADO.Net DataSet object, or executes a WMI query and stores the results in a ArrayList object. In both cases, the resulting collection is then databound to a grid in the template. The function name is auto-generated form the source data object. For example, generating a grid from the Products table in a database would generate a function called: GridQuery-AdventureWorks2012_Production_Product. A WMI object would generate a function called: WMIGridQuery-CIMV2-Win32_Share.
  2. %GridFunctionCall%
    Having a data retrieval function is useless unless you call it. This is the purpose of this placeholder. Adding this placeholder into an event handler will ensure that the data retrieval function is called when that event fires. Typically you would provide a 'Load' button in your template so that users can choose when you retrieve data. This placeholder would be added to the click event handler for the button.
  3. %ResultsFunction%
    This placeholder is replaced by a function declaration that returns the results of a query.
  4. %ResultsFunctionCall%
    This placeholder is replaced by a call to the results function.

If you open the form file 'Grid Template.psf' from the built in grid template stored in %ProgramData%\SAPIEN\PowerShell Studio 2014\Templates\Grids\Grid Template and examine the code, you will find the placeholders.

Once the template has been used against a WMI object, the generated code looks like this:

These placeholders allow you to control exactly how a user can interact with data, while leaving PowerShell Studio to write the data retrieval code.

When you create a grid template from an existing form, PowerShell Studio will clearly indicate that you have not included the placeholders in your code.

You can elect not to include them if you would rather provide a fixed data retrieval implementation.

Exporting Scripts and Packages

You can export a script or package directly from the Export tab of the ribbon:

Exporting creates a single stand-alone script that encapsulates all of the content of a script or package. The exported code can be placed on the clipboard or stored in a file. In both cases, PowerShell Studio adds assembly load statements to the front of the exported code to make sure that it runs in the same environment.

PowerShell Studio can also add metadata, called recovery data, to the script created by the export process. This metadata allows PowerShell Studio to recreate the original project that was used during the export. Recovery data embedding is enabled on the Designer tab of the Options dialog on the Home ribbon as displayed below.

Chapter 9 will cover the recovery options in detail.

When an exported script is opened in PowerShell Studio and recovery data is present, PowerShell Studio will offer you the option of using the recovery data to recreate the project that was used to create the script. Alternatively, you can simply open the script in the code editor.

Initializing my GUI Controls

If you are working with a GUI script within PowerShell Studio and find that you need to edit the exported script to modify the control's initialization, then you are doing something wrong. Don't get us wrong, modifying and initialization of control properties is not the issue; in fact that is part of writing a GUI. What we're more referring to is the part where you are editing the exported scripts.

If you are editing the exported script:

  1. You are creating an extra step which means you need to export and modify the script anytime you make a change to the original file.
  2. It is time consuming and unproductive
  3. If you are working with Source Control or within a team environment, chances are the change will be missed or forgotten by somebody.

So the main question here is: If I'm not supposed to edit the exported script, then how do I initialize my controls?

Thankfully WinForms provides a convenient place to initialize your GUI controls, the Form control's Load event. The Form control's Load event is called right before the form is displayed, which makes it a perfect place to initialize your controls.

WARNING: Do not try to initialize a control outside an event block within the script.

  1. The control might not exist when this line is executed by PowerShell.
  2. If the control does exist, your changes will most likely get overwritten by the designer generated script.

Alternatives to the Load event

It is possible to use other events to trigger initialization. For example, some control sets such as the Chart - Disk Space use the VisibleChanged event to trigger initialization. This event is triggered when the control is displayed (such as when the form is loaded) or hidden using the Visible property.

In the sample above, the control set initializes when the control becomes visible by checking its Visible property.

If your initialization script is running slow, it can prevent the GUI from displaying in a timely manner or cause it to hang. In instances such as this, you might want to delay your initialization or simply run the query in a separate job, then initialize and enable the controls after the job has completed the query.

WARNING: You cannot access GUI controls directly from a Job. You must return the results first and then initialize the controls on the main thread / script.

Control Helper Functions

Some controls are relatively complicated to work with directly from PowerShell, and may require custom .Net code to be able to access all of their features. For those controls, PowerShell Studio automatically creates helper functions that add useful .Net based methods into the form.

For example, when you add a ListView control to a form, PowerShell Studio adds two helper functions:

  1. Sort-ListViewColum
    This function enables sorting on any of the ListView's columns.
  2. Add_ListViewItem
    This function provides an easy way to add items to a ListView

To demonstrate this, create a new empty form in PowerShell Studio and look at the script that has been created.

Now add a ListView control to the form and examine the code again. In the screenshot below, the helper functions have been folded to reduce the size of the image.

A region called 'Control Helper Functions' has been added to the form and two functions have been defined.

Adding Custom Helper Functions

As you build larger and more complex scripts, you will find it useful to build up a collection of helper functions. Control helper functions are stored in the following folder:

%ProgramData%\SAPIEN\PowerShell Studio 2015\Templates\Control Functions

Each control that has helper functions will have a folder named after the control. This is the default set delivered with PowerShell Studio 2015:

Each of these directories contains one or more PowerShell scripts that will be merged into existing code when the control is added to a form.

If we wanted to add a helper function to textbox controls, the first step would be to create a folder called System.Windows.Forms.TextBox in this folder. Note: The folder must match the control type's full name.

Next we would create one or more scripts, one for each helper function. It is important that the name of the function is the same as the name of the script file, and that only one file is included per script. In this case, we will add the script shown below. This sample function coverts the text in a textbox to upper case.

Now when we add a textbox to a form in PowerShell Studio, our helper function will be included along with the standard code as shown below:

Helper Function Rules:

  1. The folder must be named after the control type's full name.
  2. File's name must match the function's name.
  3. Each file should only contain a single function.

Failure to follow these rules can result in the insertion of multiple copies of the same function.

Property Sets

A property set is a collection of property settings that can be applied together to one or more controls.Property Sets allow you to create a consistent look and feel for your GUIs; they are similar to the web concept of CSS files. A property set can be generic or specific to a particular type of control.

Applying Property Sets

Property sets are applied by selecting one or more controls on a form, pressing the Apply Property Set button on the Designer ribbon, pressing Ctrl+L, or by right-clicking on the control and choosing Apply Property Set from the menu.

This will display the Property Set Template picker.

In this case, we are applying a property set to a button control. PowerShell Studio is showing four general styles and two that are specific to Buttons.

If you check the 'Show property sets for same type only' check box, the style list will be filtered to leave only styles that apply directly to the selected control type, as shown below.

Now click on the style you wish to apply and press Select to apply it.

NOTE: If you modify a property set after you have applied it to controls, you must reapply it to those controls. Your changes will not be automatically applied.

Creating Property Sets

You can create your own property sets that encapsulate local branding requirements or other useful settings. To do this, first set all of the control properties that you want to capture. Then select a control and press the Create Property Set button on the Designer ribbon or press Ctrl+Shift+L.

When the Create Property Set Template dialog appears, select the properties that should be captured by the property set. Use the Limit to: selector to specify whether your new property set can be used with any control, or only controls that are the same type as the source control. You must also add a description before you can save the new property set.

The next time you apply a property set, your new property set will appear in the list of possible choices.

There is currently no way to alter a property set. They must be re-created and re-applied to the control.

Control Sets

In the same way that property sets allow you to group together property settings for reuse, control sets allow you to combine multiple controls and script code into new custom controls that can be added to forms just like standard controls.

Inserting Control Sets

PowerShell Studio provides a useful set of Control Sets. They are shown on the Control Sets tab of the Toolbox.

These control sets address a number of common scenarios in PowerShell scripting. To use them, simply drag one onto a form and, if necessary, add code to integrate it into your script. In some cases, a control set will need to add code to certain event handlers before it can work. PowerShell Studio will display the following dialog if this is required.

You can select from the following options:

When you select the new Append option, the form's event is assigned below the new event script block:

Now you can use multiple controls sets that share the same events without them interfering with one another.

Choosing Between Leave and Replace

In the code shown below, the form load event handler ($form1_Load) has been customized to write information to the debug pipeline.

We can see from the form properties that this handler has been connected to the form's Load event:

If we now add the 'Fade in Effect' control set and choose replace, the following changes occur:

  1. New code is added, without affecting any existing code
  2. The form's Load event is connected to the new code

This provides a nice fade in effect but our Write-Debug statement is no longer executed. To fix this, reconnect the form's Load event to the original event handler, form1_Load, and modify the event handler to call the new control set code.

The following line will execute the code stored in the variable $form1_FadeInLoad:

&$form1_FadeInLoad

Choosing Leave would have added the control set code without connecting the form's load event to the new event handler, thus leaving it to us to connect things as we see fit.

Creating Control Sets

Creating your own control sets is another great way to build reusable components for your scripting tasks.

Start by adding controls to a form, configuring their properties, and writing all of the code required to make your new control set function correctly. Once done, select all of the controls that are to be included in the control set and press Ctrl+T or right click on the code editor pane and choose Create Control Set.

The Create Control Set dialog allows you to set the properties of your new custom control. On the General tab:

When you press Next you will be taken to the Functions tab where you can choose to include any functions from your code in the template.

PowerShell Studio will automatically include functions that are bound to events in the control.

Next is the Events tab, where you can mark an event as shared. When you check the "Shared" checkbox next to an event, it will tell PowerShell Studio to share the event over multiple instances of the control set. It does this by first checking if the event already exists. If the event does not exist, then it will insert the event. If it does exist, it will simply use the existing script block whenever a control triggers the event.

The TextBox-Watermark control set in PowerShell Studio 2015 serves as a perfect example as to where you would use a shared event. The script blocks to display the watermark, is identical for all instances of the control set, and thus doesn't make sense to create a new instance of the same event block every time the control set is inserted.

Click on Finish and give your Control Set a name. It will now be added to the Toolbox.

If you include an entire form in a control set, PowerShell Studio will add an extra tab to the Create Control Set dialog.

The container tab helps you to specify which form property values and event handlers should be included in the control set. The next time you need to use your new control set, simply drag it from the toolbox onto a form.