Content for this blog post, also available here : https://github.com/1RedOne/BlogPosts/tree/master/ContinuousAutomation/Post2
ContinuousAutomation Part II PowerShell GUIs
[void][System.Reflection.Assembly]::LoadWithPartialName('presentationframework') | |
$xamlPath = "$($PSScriptRoot)\$((split-path $PSCommandPath -Leaf ).Split(".")[0]).xaml" | |
if (-not(Test-Path $xamlPath)){ | |
throw "Ensure that $xamlPath is present within $PSScriptRoot" | |
} | |
$inputXML = Get-Content $xamlPath | |
$inputXML = $inputXML -replace 'mc:Ignorable="d"','' -replace "x:N",'N' -replace '^<Win.*', '<Window' | |
[xml]$XAML = $inputXML | |
$reader=(New-Object System.Xml.XmlNodeReader $xaml) | |
try{ | |
$Form=[Windows.Markup.XamlReader]::Load( $reader ) | |
} | |
catch [System.Management.Automation.MethodInvocationException] { | |
Write-Warning "We ran into a problem with the XAML code. Check the syntax for this control..." | |
write-host $error[0].Exception.Message -ForegroundColor Red | |
if ($error[0].Exception.Message -like "*button*"){ | |
write-warning "Ensure your <button in the `$inputXML does NOT have a Click=ButtonClick property. PS can't handle this`n`n`n`n"} | |
} | |
catch{ | |
Write-Host "Unable to load Windows.Markup.XamlReader. Double-check syntax and ensure .net is installed." | |
} | |
#=========================================================================== | |
# Store Form Objects In PowerShell | |
#=========================================================================== | |
$xaml.SelectNodes("//*[@Name]") | %{Set-Variable -Name "WPF$($_.Name)" -Value $Form.FindName($_.Name)} | |
Function Get-FormVariables{ | |
if ($global:ReadmeDisplay -ne $true){Write-host "If you need to reference this display again, run Get-FormVariables" -ForegroundColor Yellow;$global:ReadmeDisplay=$true} | |
write-host "Found the following interactable elements from our form" -ForegroundColor Cyan | |
get-variable WPF* | |
} | |
Get-FormVariables | |
function loadListView(){ | |
$global:deviceList = new-object -TypeName System.Collections.ArrayList | |
$devices = import-csv "$PSScriptRoot\devices.csv" | Sort-Object Processed | |
ForEach($device in $devices){ | |
$global:deviceList.Add($device) | |
} | |
$WPFdevice_listView.ItemsSource = $global:deviceList | |
} | |
function cancelButton(){ | |
$WPFok.IsEnabled = $false | |
$wpfdeviceTextbox.Text = $null | |
$wpflabelCounter.Text="Reset" | |
} | |
$wpfdeviceTextbox.Add_TextChanged({ | |
if ($wpfdeviceTextbox.Text.Length -le 5){ | |
return | |
} | |
$WPFok.IsEnabled = $true | |
$deviceTextbox = $wpfdeviceTextbox.Text.Split(',').Split([System.Environment]::NewLine).Where({$_.Length -ge 3}) | |
$count = $deviceTextbox.Count | |
$wpflabelCounter.Text=$count | |
}) | |
$WPFCancel.Add_Click({ | |
cancelButton | |
}) | |
$WPFok.Add_Click({ | |
$deviceTextbox = $wpfdeviceTextbox.Text.Split(',').Split([System.Environment]::NewLine).Where({$_.Length -ge 3}) | |
ForEach($item in $deviceTextbox){ | |
$global:deviceList.Add([pscustomObject]@{HostName=$item}) | |
} | |
set-content "$PSScriptRoot\devices.csv" -Value $($deviceList | ConvertTo-csv -NoTypeInformation) | |
cancelButton | |
loadListView | |
}) | |
loadListView | |
$Form.ShowDialog() | out-null |
<Window x:Class="WpfApp2.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:WpfApp2" | |
mc:Ignorable="d" | |
Title="MainWindow" Height="1000" Width="800"> | |
<Grid Background="#FF0B4A80"> | |
<Grid.RowDefinitions> | |
<RowDefinition Height="1*"/> | |
<RowDefinition Height="6*"/> | |
<RowDefinition Height="10*"/> | |
</Grid.RowDefinitions> | |
<Grid.ColumnDefinitions> | |
<ColumnDefinition Width="3*"/> | |
<ColumnDefinition Width="1*"/> | |
</Grid.ColumnDefinitions> | |
<StackPanel Grid.Row="0" Grid.ColumnSpan="2"> | |
<TextBlock FontSize="22" Foreground="#FFFFF7F7" Grid.ColumnSpan="2">FoxDeploy Device Scheduler</TextBlock> | |
<Separator /> | |
</StackPanel> | |
<StackPanel Grid.Row="1" Grid.Column="0"> | |
<TextBlock FontSize="14" Foreground="#FFFFF7F7">Paste a list of devices into the textbox below to add them to the database to be processed!</TextBlock> | |
<TextBox x:Name="deviceTextbox" Width="450" Height="240" HorizontalAlignment="Left" TextWrapping="Wrap" AcceptsReturn="True"></TextBox> | |
<TextBlock FontSize="18" Foreground="#FFFFF7F7">New Device Count <TextBlock x:Name="labelCounter" Foreground="Yellow" FontSize="22" HorizontalAlignment="Center" VerticalAlignment="Bottom">Waiting...</TextBlock></TextBlock> | |
</StackPanel> | |
<StackPanel Grid.Row="1" Grid.Column="1"> | |
<Button x:Name="ok" Content="OK" Width="100" IsEnabled="False"/> | |
<Button x:Name="Cancel" Content="Cancel" Width="100"/> | |
</StackPanel> | |
<StackPanel Grid.Row="2"> | |
<TextBlock FontSize="20" Foreground="#FFFFF7F7">Scheduled Devices</TextBlock> | |
<Separator /> | |
<TextBlock FontSize="14" Foreground="#FFFFF7F7">The devices below have already been scheduled!</TextBlock> | |
<ListView x:Name="device_listView" MaxWidth="800" HorizontalAlignment="Left"> | |
<ListView.View> | |
<GridView> | |
<GridViewColumn Header="HostName" DisplayMemberBinding ="{Binding 'HostName'}" Width="120"/> | |
<GridViewColumn Header="Processed" DisplayMemberBinding ="{Binding 'Processed'}" Width="80"/> | |
<GridViewColumn Header="Processed Date" DisplayMemberBinding ="{Binding 'ProcessedDate'}" Width="180"/> | |
</GridView> | |
</ListView.View> | |
</ListView> | |
</StackPanel> | |
</Grid> | |
</Window> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment