Building a PowerShell GUI (Part 2)
If you would like to read the other parts in this article series please go to:
- Building a PowerShell GUI (Part 1)
- Building a PowerShell GUI (Part 3)
- Building a PowerShell GUI (Part 4)
- Building a PowerShell GUI (Part 5)
- Building a PowerShell GUI (Part 6)
- Building a PowerShell GUI (Part 7)
- Building a PowerShell GUI (Part 8)
- Building a PowerShell GUI (Part 9)
- Building a PowerShell GUI (Part 10)
- Building a PowerShell GUI (Part 11)
- Building a PowerShell GUI (Part 12)
- Building a PowerShell GUI (Part 13)
In my previous article, I explained that it is possible to build PowerShell scripts that have a graphical user interface, but that in order to do so you will have to delve into the world of Visual Studio. In this article, it’s time to get our collective hands dirty and get to work building a graphical interface.
For the purposes of this article, I am assuming that you already have a PowerShell script that you want to use. For the sake of demonstration, I will start with a simple script, but everything that I will be showing you can be applied to more complex scripts.
So to get started, go ahead and launch Visual Studio. All of my instructions in this article will be based around the use of Visual Studio 2015 Professional with Update 1. When Visual Studio starts, click on the New Project link.
At this point, you will see a really cluttered screen asking you what type of project you want to create. Type WPF into the Search box (I am assuming that Visual Studio is configured for general use) and then choose the WPF Application option (I will be using the template for Visual C#).
If you think back to the previous article, you will recall that I mentioned that we will be using PowerShell and XAML, but I never said anything about WPF. WPF is the Windows Presentation Foundation. It is a part of the .NET Framework and is a rendering engine for graphical applications. As we work with WPF, we will be creating the required XAML file.
So with that said, go ahead and give your project a custom name and click OK. As you can see in Figure A, I am calling my project PowerShellGUISample.

Figure A: Choose the WPF Application template and assign a name to your project.
Now you will be taken to the screen that you will be using to develop your project. If you look closely at Figure B, you will notice that there is some XAML code shown at the bottom of the screen. Although this code does not do anything, you will eventually be able to copy and paste code directly from this window into an XAML file.

Figure B: This is the screen that is used for developing the project.
With that said, I want to get started by showing you how to build a really simple GUI. Once this GUI is functional then my plan is to show you how to create something more useful.
Begin the process by creating two folders on your hard disk. One of these folders should be called Forms and the other should be called Scripts. The Forms folder will store the XAML files that you create, while the Scripts folder will store PowerShell scripts. Technically, you don’t have to use two different folders, and you can use any folder names that you want, but it is generally advisable to store scripts in a separate location from XAML files.
Now, let’s create the first PowerShell script. This script should reside in the C:\Scripts folder and should be called LoadDialog.ps1. This is the script that does all of the heavy lifting. The script brings together the Windows Presentation Foundation and various .NET assemblies in order to render the graphical interface. The good news is that you do not have to create this form from scratch. Microsoft has already built the script for you. In fact, the simple GUI interface that I am going to show you how to create borrows heavily from this article. Once I’ve covered the basics then I will of course give you some code that is more original. With that said, here is the code that you will need to add to the LoadDialog.ps1 file:
[code]
[CmdletBinding()]
Param(
[Parameter(Mandatory=$True,Position=1)]
[string]$XamlPath
)
[xml]$Global:xmlWPF = Get-Content -Path $XamlPath
#Add WPF and Windows Forms assemblies
try{
Add-Type -AssemblyName PresentationCore,PresentationFramework,WindowsBase,system.windows.forms
} catch {
Throw "Failed to load Windows Presentation Framework assemblies."
}
#Create the XAML reader using a new XML node reader
$Global:xamGUI = [Windows.Markup.XamlReader]::Load((new-object System.Xml.XmlNodeReader $xmlWPF))
#Create hooks to each named object in the XAML
$xmlWPF.SelectNodes("//*[@Name]") | %{
Set-Variable -Name ($_.Name) -Value $xamGUI.FindName($_.Name) -Scope Global
}
[/code]
The next thing that we have to do is to design the GUI interface. As I said earlier, I am going to start out by partially following the Microsoft example. To create the GUI, switch back over to Visual Studio and then open the Toolbox by clicking on the Toolbox link on the left side of the screen (you can also use the View menu). When you open the toolbox, you will see a series of items that you can add to the GUI. Simply drag these items from the toolbox to the GUI. For the sake of demonstration, I have added a label and a button, as shown in Figure C.
Figure C: I have added a label and a button to the GUI.
As you add these elements to the GUI, the source code at the bottom of the screen is updated automatically. Go ahead and copy the source code into a text file and then save the file into the C:\Forms folder as MyForm.XAML. Here is the code that was generated by Visual Studio:
[code]
<Window x:Class="PowerShellGUISample.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:PowerShellGUISample" mc:Ignorable="d" Title="MainWindow" Height="350" Width="525">
<Grid>
<Button x:Name="button" Content="Button" HorizontalAlignment="Left" Margin="249,132,0,0" VerticalAlignment="Top" Width="75"/>
<Label x:Name="label" Content="Label" HorizontalAlignment="Left" Margin="88,73,0,0" VerticalAlignment="Top"/>
</Grid>
</Window>
[/code]
As it stands right now, this code is almost usable, but not quite. We have to make a few minor modifications.
As you look at the code above, you will notice that there is a line that starts with <Button and a line that starts with <Label. Both of these lines include x:Name=. In order to make this code work correctly, you will need to get rid of X:. It is also very important to understand that whatever name you choose to assign through the Name attribute will become the name of a PowerShell variable later on. For the sake of demonstration, I will use the names MyButton and MyLabel.
We also need to make is to delete these lines:
[code]
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:PowerShellGUISample"
mc:Ignorable="d"
[/code]
Finally, we have to get rid of the X:Class section in the first line. Here is what the modified code looks like:
[code]
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="350" Width="525">
<Grid Background="#FFB7C9C4">
<Button Name="MyButton" Content="Button" HorizontalAlignment="Left" Margin="249,132,0,0" VerticalAlignment="Top" Width="75" Background="#FF057DF5" Foreground="#FFFDF9F9" BorderBrush="#FF171717"/>
<Label Name="MyLabel" Content="Label" HorizontalAlignment="Left" Margin="88,73,0,0" VerticalAlignment="Top"/>
</Grid>
</Window>
[/code]
The last thing that we need to do is to create our main PowerShell script. I am going to call this script HelloWorld.ps1. Since I am trying to keep this simple, the Hello World script is very short and straightforward. Here is the script that I am using:
[code]
#Required to load the XAML form and create the PowerShell Variables
./LoadDialog.ps1 -XamlPath ‘C:\Forms\MyForm.xaml’
#EVENT Handler
$MyButton.add_Click({
$MyLabel.Content = “Hello World”
})
#Launch the window
$xamGUI.ShowDialog() | out-null
[/code]
The first section loads the LoadDialog.ps1 file and the MyForm.xaml file. The second section is an event handler. This section tells PowerShell to replace the contents of the label with the phrase Hello World when the button is clicked. The final section is what causes the GUI to actually be displayed. I realize that I have given you a very brief description of what this script does, but I will be covering the script in greater depth when we adapt it to a more useful purpose later on.
For right now, I want to show you what happens when we run the HelloWorld.ps1 script. Before executing the script, be sure to set PowerShell’s execution policy to allow the script to run. With that said, running the script will produce the screen shown in Figure D. Notice that the text says Label.
Figure D: This is what is displayed when the script is run.
When we click the button, Label is replaced by Hello World, as shown in Figure E.
Figure E: Clicking the button causes Hello World to be displayed.
Conclusion
In this article, I have shown you how to create a very simple PowerShell GUI. You can download the working script files in a zip package from here.
In my next article, I want to begin showing you how to make the GUI do something more useful.