Building a user interface (UI) in PowerShell may sound like a difficult process and you may not even know where to begin to accomplish something like this. Luckily, there are a few choices on what you can use to create a simple or complex UI that can be handed off to an individual to use with little to no effort. Whether you use WinForms of WPF as your building block for your UI, you still have more options with each to help build a nice UI. For the sake of this series of articles, I am going to be focusing on WPF and will show some of the controls that you can use to build a nice application for others to use.
With WPF, you have options on what you want to use to build out the interface. ShowUI, XAML and .Net are the most common ways to accomplish this. Each has its own strengths to use, but I personally usually stick with using XAML and sometimes use .Net to build dynamic controls on the fly if needed. But whatever path you choose is completely up to you as either of these ways will get you to your goal.
My goal with this is to start from the beginning and try to cover some basics of working with WPF and PowerShell over time. This is by no means a comprehensive all in one WPF guide. That would take up too much time and there are many things that I still do not know at this time. With that, this means that am I an expert at this (I’m an ITPro, not Dev
) but I have been able to build a few UI’s (PoshPAIG, PoshChat, Profile Removal, etc…) and want to share my knowledge with others and also provide a reference for myself in the process!
XAML or .Net?
Both actually! I won’t actually show both ways to accomplish the same task, but I will start out with the XAML approach and make updates to the existing object using PowerShell/.Net.
Loading the XAML With PowerShell
In every initial example, you will see me take the XAML code and plug it into PowerShell to display. In order to do this, I need to cast the data as xml using [xml] and then loading up the xml into PowerShell using System.Xml.XmlNodeReader and [Windows.Markup.XamlReader]::Load.
#Build the GUI
[xml]$xaml = @"
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Name="Window" Title="Initial Window" WindowStartupLocation = "CenterScreen"
Width = "800" Height = "600" ShowInTaskbar = "True">
</Window>
"@
$reader=(New-Object System.Xml.XmlNodeReader $xaml)
$Window=[Windows.Markup.XamlReader]::Load( $reader )
The Initial Window
This really is the starting point for most of your WPF UIs. The Window itself. I will be using the same code as above to demonstrate the initial Window. After which, I will rely on using Powershell to adjust or add various things to the existing object. You can find a plethora of information here on the msdn page.
Because this is going to be a generic Window with nothing spectacular, I will make the Width 800 and the Height 600 while starting the window up in the Center screen by setting WindowStartupLocation to ‘CenterScreen’. I also chose the name the Window as ‘Windows’ which is done in XAML by specifying x:Name = ‘Window’. And yes, when you are working in XAML, the properties are Case Sensitive! After loading up the code into PowerShell as an object, you can start the Window up by using the ShowDialog() method. Do not use Show() unless you want to lock up your console or ISE!
So lets go ahead and check out this exciting Window!
$Window.ShowDialog()
As you can see, nothing that groundbreaking. The window did come up in the center screen along with the size being what I set. The title also shows up correctly. You can close the window simply by clicking on the red X. Also, when you close the window, you will see $False appear on the console.
Properties You May Find Useful
Now that we have the window up and running, we can look at few of the properties that you may wish to use to make the window look a little nicer. In case you are wondering why I said a few, it is because there are a ton of properties and many of those will go beyond the scope of what I plan to do here.
ToolTip
A tooltip provides a message to the user simply by hovering the mouse cursor over the object, in this case, the window.
$window.ToolTip = "This is a window. Cool, isn't it?"
Transparency
You can set the Window to be transparent if you’d like. A word of caution is that you will lose your ability to close the Window with the red X. You will need to configure an alternate means of closing the window (see the event for Click To Close later in this article). You will need to set the 3 items posted in the source code below. The Opacity must be a value between 0 and 1.0 in order to work properly
$Window.AllowsTransparency = $True $Window.Opacity = .5 $window.WindowStyle = 'None'
As you can see, it is transparent with no visible way to close it!
Background Color
Setting the background color of your window is simple! Just use the Backgroundcolor property and give it a color!
$Window.Background = 'Green'
Adding Text To Your Window
Besides adding a background color, you can add text to your Window via the Content property. Besides that, you can customize your text using a variety of methods listed below in the code.
$Window.FontSize = 24 $Window.FontStyle = 'Italic' #"Normal", "Italic", or "Oblique $Window.FontWeight = 'Bold' #http://msdn.microsoft.com/en-us/library/system.windows.fontweights $Window.Foreground = 'Red' $Window.Content = "This is a test!"
Events You May Find Useful
Events are designed to fire off when a certain action occurs. Whether it is a timed event that fires on a tick, or a mouse click or even if the Window is closing or opening. You can supply a script block to the action block of the event to perform whatever task it is you need done with the event. Be sure to include all of the events prior to the code that is opening the Window, otherwise you might be left wondering what is going on.
Click To Close
As seen in my demo of a transparent window, there will be a time when you might need an alternate way to close the window. Luckily, that can be done with your mouse just by clicking on the window with either your left or right mouse button and using the $Window object’s Close() method. In this case, I am going to close the Window using the Right mouse button.
$Window.Add_MouseRightButtonDown({
$Window.close()
})
Click To Drag
Same issues with using transparency means that you have no real way to move your window around. We get around that by once again using the MouseRight/LeftButton event and then using the DragMove() method.
$Window.Add_MouseRightButtonDown({
$Window.DragMove()
})
Actions To Perform On Close
When your window closes, you may need to perform some additional tasks such as saving to a config file, cleanup, etc… Luckily we can use the Closed event with whatever actions that need to be taken to accomplish this.
$Window.Add_Closed({
Write-Verbose "Performing cleanup"
})
Actions To Perform On Open
When your Window first opens up, you may need to perform some initializations before presenting everything to the user. For this approach, I typically use the OnLoaded event.
$Window.Add_Loaded({
Write-Verbose "Starting up application"
})
Timer Event
Sometimes you need a timer to handle certain actions on each tick. The approach I usually take is to initialize my timer when the window is loaded and then supply the code that that will run on each tick of the timer.
$Window.Add_Loaded({
$timer.Add_Tick({
[Windows.Input.InputEventHandler]{ $Global:Window.UpdateLayout() }
#Write-Verbose "Updating Window"
})
#Start timer
Write-Verbose "Starting Timer"
$timer.Start()
})
Wrapping Up
That concludes the initial article on WPF and building your first Window. Like I said at the beginning, this is just 1 step on a multi-step process to really create something cool. If you have anything that you would like to see about a specific control that I talk about, feel free to leave something in the comments. If there is something that you would like to see me tackle, let me know and I will see what I can do and hopefully we will learn something new together!
Next WPF Topic
Buttons






Hey Guys, I found an even easier way to load a XML-String:
$window = [Windows.Markup.XamlReader]::Parse( ([string] @”xamlcontent”@) )
Saves another few lines …
Excellent! Thanks for sharing!
I have a third party application using xaml do open dialog windows. The dialofg windows require to be closed by ok or cancel buttons and can be customized to a large extent eg import xaml code.
BUT i need to close these windows upon external events e.g. a time point.
Can I use Power shell to close such a window :
based on the window tile?
Thanks, Gernot
Pingback: Episode 202 – Antoine Habert talks about PoshBoard « PowerScripting Podcast
Great post Boe. Just this first XAML post has convinced me to take another look at using XAML for some future projects instead of WinForms. Looking forward to see more in this series. When you started learning XAML, did you use a GUI-building app similar to PowerShell Studio for WinForms?
Thanks, Rich! I just starting looking at some other sites on working with XAML or that had examples that I could reference and just started to put things together. I know that you can use Visual Studio where you can build out the UI and then copy the XAML code (with a couple modifications) and start using that in your PowerShell code.
Boe,
Another great post. I too had tried the ShowUI after watching a James Brundage webcast.
The documentation was a little lite – but your explanations are helping to fill in the gaps.
Keep em coming please.
Peter
Thanks Peter! Glad you enjoyed the initial article. I have plans to work with a control in each article and show some basic things with each control.
Thanks for this great article. I already tried ShowUI but find it too difficult to start with. Your tips gave me a good start even for someone with no experience. Could you maybe show how to create a File menu or how to add controls like buttons,radio or check boxes. Thanks in advance.
Hi Gyz. Glad you enjoyed the article! Buttons are next on my list and I will be doing radio and check boxes at some point in the future as well. I will also touch on Menus and will show what I did for a File menu in one of my projects.