Currently I am working on rewriting all my VBscript and Powershell GUI script using WPF (Windows presentation platform). When building a graphical xaml forms on Visual studio as shown earlier on Part 1: Create WPF XAML powershell GUI form with Visual studio, I had to remove many elements manually by finding them, and every time it is not productive at all, if I missed removing any unwanted element, it was causing errors. To illustrate it, earlier I was removing lots of stuff from XAML form, But in this demo I will remove only 2 Lines 'x:Class="WPFapplication2.MainWindow"' and 'mc:Ignorable="d"'. This is one time process. I will be keeping xmlns namespaces. Alternatively I can also keep this entire code in external file to reduce code on ps1 file.
Line 24 and 25 are same earlier shown article Part 2: Powershell and WPF: Build GUI applications tutorial, Next line 28 is important one. Once XAML form is parsed by finding nodes and shows the list of allcontrols. Using Foreach-Object I can create a variable for each control so it can be used to perform actions. I don't have to worry about adding new FindName method everytime, it is automated now.
$xaml.SelectNodes("//*[@*[contains(translate(name(.),'n','N'),'Name')]]").Name
Below is the gif animation of the script, it is working perfectly and my code is very much shorter now, and if I add new control in the XAML
Download script here, this is also available on GitHub.com.
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 77 78 79 80 81 |
#Load required libraries Add-Type -AssemblyName PresentationFramework, PresentationCore, WindowsBase, System.Windows.Forms, System.Drawing [xml]$xaml = @" <Window 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:WpfApplication2" Title="MainWindow" Height="300" Width="364"> <Grid> <TextBox x:Name="textBox" HorizontalAlignment="Left" Height="23" Margin="10,41,0,0" TextWrapping="Wrap" Text='$env:ComputerName' VerticalAlignment="Top" Width="225"/> <Label x:Name="label" Content="ComputerName or IP" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" Width="175"/> <Button x:Name="button" Content="Get-DiskInfo" HorizontalAlignment="Left" Margin="240,41,0,0" VerticalAlignment="Top" Width="105" Height="24"/> <DataGrid x:Name="dataGrid" HorizontalAlignment="Left" Margin="10,69,0,0" VerticalAlignment="Top" Width="335" Height="141"/> <Label x:Name="label1" Content="http://vcloud-lab.com" HorizontalAlignment="Left" Margin="221,215,0,0" VerticalAlignment="Top" Width="125" Foreground="#FF0000EE"/> </Grid> </Window> "@ #Read the form $Reader = (New-Object System.Xml.XmlNodeReader $xaml) $Form = [Windows.Markup.XamlReader]::Load($reader) #AutoFind all controls $xaml.SelectNodes("//*[@*[contains(translate(name(.),'n','N'),'Name')]]") | ForEach-Object { New-Variable -Name $_.Name -Value $Form.FindName($_.Name) -Force } $textBox.Add_GotFocus({ if ($textBox.Text -eq '' -or $textBox.Text -match '\s+') { $textBox.Foreground = 'Black' $textBox.Text = '' } }) $textBox.Add_LostFocus({ if ($textBox.Text -eq '' -or $textBox.Text -match '\s+') { $textBox.Foreground = 'Black' $textBox.Text = 'Type valid computername' $textBox.Foreground = 'Darkgray' } }) function Get-DiskInfo { if ($textBox.Text -eq '') { $textBox.Text = "Type valid computername" $dataGrid.ItemsSource = $null } else { try { $DiskInfo = Get-CimInstance -ClassName Win32_Logicaldisk -ComputerName $textBox.Text -ErrorAction Stop | Select-Object DeviceID, DriveType, @{N='FreeGB'; E={[Math]::round($_.FreeSpace/1GB)}}, @{N='TotalGB'; E={[Math]::round($_.Size/1GB)}} } catch { $dataGrid.ItemsSource = $null $textBox.Text = "Can't Connect server" $textBox.Foreground = 'Red' } } $DiskList = New-Object System.Collections.ArrayList if ($DiskInfo -ne $null) { $DiskList.AddRange($DiskInfo) $dataGrid.ItemsSource = $DiskList } } #What happens when button is clicked $button.Add_Click({Get-DiskInfo}) #Link Label $label1.Add_MouseLeftButtonUp({[system.Diagnostics.Process]::start('http://vcloud-lab.com')}) $label1.Add_MouseEnter({ $label1.Foreground = 'Purple' }) $label1.Add_MouseLeave({ $label1.Foreground = 'Blue' }) #Mandetory last line of every script to load form $Form.ShowDialog() |
Userful Articles
Part 1: Create WPF XAML powershell GUI form with Visual studio
Part 2: Powershell and WPF: Build GUI applications tutorial
COOL POWERSHELL FREE ONLINE GUI GENERATOR TOOL, POSHGUI
Generate random password GUI using powershell