Part 1: Create WPF XAML powershell GUI form with Visual studio

Part 2: Powershell and WPF: Build GUI applications tutorial

WPF stands for Windows Presentation Foundation, it is an alternative technology to Windows Forms but not a replacement. In this demo, I am showing how to design a basic Powershell GUI utility from scratch to show first 10 event logs, when system was restarted (including unexpected and initiated by users restart logs).

For this tutorial I used Windows 7 (Powershell V4) and Vistual studio community 2015. In earlier chapter, I already shown how GUI form is designed and created, once it is launched, tool looks like below, In the computer or IP box type valid hostname, once Get-RestartLogs button is pressed it will fetch the result and shows in the nice DataGrid view table. If invalid or unreachable or no computer name is typed, it shows user friendly error message.

Below WPF GUI form is created using Visual Studio community version 2015, Here in this GUI script it fetches last 10 reboot events, If you don't type anything or if invalid computer name or IP or if it is blank, it will popup error once Get-RestartLogs button is press, Also it validates whether computer or IP is reachable, If you have privileges to fetch event logs, It will show result in the nice table.

In the bottom I have given complete script, but Here I have broken it down in parts and explained how it is built.

Line 2: Powershell require PresentationFramework dll and included in the .NET Framework 4 Client Profile, it is a mandatory line. Without this line GUI form won't load. You can add two more libraries as below.

Add-Type -AssemblyName PresentationCore

Add-Type -AssemblyName WindowsBase

Line 5 to 26: Next I have written a function, this is executed once button is pressed. Get-RestartEventLogs function connects to ComputerName and shows newest 10 restart logs from Get-EventLog. There isn't much GUI code involved in this, except one liner MessageBoxes codes for errors if provided invalid computername/Ip or textbox is empty, Message boxes shows friendly error messages. You can run this function separately on console or ISE and result will show on it. I will use this function in the next of the code.

Line 29 to 41: I have created and designed this UI form in visual studio community edition. Which I am going to explain in another another article. this form has form, label button, textbox and datagrid controls, this is a XAML form, stored in $form variable in XML style. This code is formatted and made usable to be use in PowerShell.

Extensible Application Markup Language (XAML) is a markup language for declarative application programming. Windows Presentation Foundation (WPF) implements a XAML processor implementation, and provides XAML language support. The WPF types are implemented such that they can provide the required type backing for a XAML representation. In general, you can create the majority of your WPF application UI in XAML markup.

Line 44 to 45: Using inbuilt XAML reader we read and load the form in $XMLForm.

Line 48 to 50: Once form is read into xml format using Powershell, Controls are loaded. computer text box, button and datagrid, Now I can run the action on the selected controls.

Line 56: This creates a arraylist for datagrid control. So I can put table data in it.

Line 59 to 73: This defines what will happen once restartlog button is pressed (add_click method), I have loaded my earlier function here, Once event logs results are fetched they are shown the datagrid in table format.

Line 76: This line should always be on the last line of the code, it generates and shows the GUI form.

Download this script here Get-RestartLogsGUI.ps1. This script is also available on Github.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 #Load Assembly and Library Add-Type -AssemblyName PresentationFramework #Check server is reachable and get winevent function Get-RestartEventLogs { param ( $ComputerName = $ComputerNameBox .Text ) if ( Test-Connection $ComputerName -Quiet -Count 2) { try { $Logs = Get-EventLog -LogName System -Source user32 -ComputerName $ComputerName -Newest 10 -ErrorAction Stop foreach ( $event in $logs ) { $TempFileName = [System.IO.Path] :: GetTempFileName() $event .Message | Out-File -FilePath $TempFileName $event | Select-Object UserName, TimeWritten, MachineName, @ {N= 'Message' ; E={( Get-Content -Path $TempFileName )[0]}} } } catch { [System.Windows.MessageBox] :: Show( "Cannot retrive event logs from server $ComputerName. Check permissions." , "Server unreachable" ) } } else { [System.Windows.MessageBox] :: Show( "Provided Server is not reachable." , "Server unreachable" ) } } #XAML form designed using Vistual Studio [xml] $Form = @" <Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" Title="RestartLogs" Height="375" Width="445" ResizeMode="NoResize"> <Grid> <Label Name="ComputerLabel" Content="Computer or IP" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" Height="30" Width="110"/> <Button Name="RestartLogsButton" Content="Get-Restartlogs" HorizontalAlignment="Left" Margin="200,43,0,0" VerticalAlignment="Top" Width="126" RenderTransformOrigin="2,1.227"/> <TextBox Name="ComputerNameBox" HorizontalAlignment="Left" Height="28" Margin="125,10,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="201" ToolTip="Type valid Computer name or IP address" AutomationProperties.HelpText="Type valid Computer name or IP address"/> <DataGrid Name="ResultDataGrid" HorizontalAlignment="Left" Margin="10,70,0,0" VerticalAlignment="Top" Height="257" Width="417"/> <TextBlock Name="Url" HorizontalAlignment="Left" Margin="206,331,0,0" TextWrapping="Wrap" Text="http://vcloud-lab.com" VerticalAlignment="Top" Width="120"/> </Grid> </Window> "@ #Create a form $XMLReader = ( New-Object System.Xml.XmlNodeReader $Form ) $XMLForm = [Windows.Markup.XamlReader] :: Load( $XMLReader ) #Load Controls $ComputerNameBox = $XMLForm .FindName( 'ComputerNameBox' ) $RestartLogsButton = $XMLForm .FindName( 'RestartLogsButton' ) $ResultDataGrid = $XMLForm .FindName( 'ResultDataGrid' ) #computername to textbox $ComputerNameBox .Text = $env:COMPUTERNAME #Create array object for Result DataGrid $RestartEventList = New-Object System.Collections.ArrayList #Button Action $RestartLogsButton .add_click({ #Computer name shouldn't be null if ( $ComputerNameBox .Text -eq '' ) { [System.Windows.MessageBox] :: Show( "Please enter a valid Computername or IP before clicking Get-RestartLogs button." , "Textbox empty" ) } #Check server is reachable and get winevent $Events = Get-RestartEventLogs -ComputerName $ComputerNameBox .Text #Build Datagrid if there if ( $Events -ne 'OK' ) { $RestartEventList .AddRange( $Events ) $ResultDataGrid .ItemsSource= @ ( $RestartEventList ) } }) #Show XMLform $XMLForm .ShowDialog()

Other Powershell GUI blogs

COOL POWERSHELL FREE ONLINE GUI GENERATOR TOOL, POSHGUI

Generate random password GUI using powershell