├── .gitignore ├── manifest.txt ├── buttons ├── modules.txt ├── Help.ps1 └── SamplePage.ps1 ├── main ├── modules.txt ├── config.ps1 ├── MainProg.ps1 └── xaml-gui.xml.ps1 ├── README.md ├── backend ├── modules.txt ├── Show-Message.ps1 ├── loadDialog.ps1 ├── Console-Controls.ps1 └── Write-FormHost.ps1 ├── resources ├── beta.ico ├── prod.ico └── about.txt ├── Mod-Loader.ps1 ├── launcher.ps1 └── LICENSE /.gitignore: -------------------------------------------------------------------------------- 1 | .vscode/* -------------------------------------------------------------------------------- /manifest.txt: -------------------------------------------------------------------------------- 1 | backend 2 | main 3 | buttons -------------------------------------------------------------------------------- /buttons/modules.txt: -------------------------------------------------------------------------------- 1 | Help.ps1 2 | SamplePage.ps1 -------------------------------------------------------------------------------- /main/modules.txt: -------------------------------------------------------------------------------- 1 | MainProg.ps1 2 | config.ps1 3 | xaml-gui.xml.ps1 -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # poshgui-framework 2 | PowerShell GUI Framework for admin tools 3 | -------------------------------------------------------------------------------- /backend/modules.txt: -------------------------------------------------------------------------------- 1 | loadDialog.ps1 2 | Write-FormHost.ps1 3 | Show-Message.ps1 4 | Console-Controls.ps1 -------------------------------------------------------------------------------- /resources/beta.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/poshcodebear/poshgui-framework/HEAD/resources/beta.ico -------------------------------------------------------------------------------- /resources/prod.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/poshcodebear/poshgui-framework/HEAD/resources/prod.ico -------------------------------------------------------------------------------- /resources/about.txt: -------------------------------------------------------------------------------- 1 | PowerShell GUI Framework 2 | Copyright 2017 3 | 4 | This framework was developed to make GUI tool development simpler. -------------------------------------------------------------------------------- /main/config.ps1: -------------------------------------------------------------------------------- 1 | $version = '1.0' 2 | $fullVersion = '1.0.0' 3 | $BetaBuild = $false 4 | 5 | if ($BetaBuild) {$icon = 'beta'} 6 | else {$icon = 'prod'} 7 | 8 | # Not used in examples, but useful 9 | $RootDir = $MyInvocation.PSScriptRoot -------------------------------------------------------------------------------- /backend/Show-Message.ps1: -------------------------------------------------------------------------------- 1 | function Show-Message 2 | { 3 | [CmdletBinding()] 4 | param( 5 | [Parameter(Mandatory = $true)] 6 | [string]$Title, 7 | 8 | [Parameter(Mandatory = $true)] 9 | [string]$Message 10 | ) 11 | [System.Windows.MessageBox]::Show($Message, $Title) 12 | } -------------------------------------------------------------------------------- /Mod-Loader.ps1: -------------------------------------------------------------------------------- 1 | # Loads in the manifest of directories to process 2 | $moduleGroups = Get-Content -Path "$($sPath)\manifest.txt" 3 | 4 | foreach ($group in $moduleGroups) 5 | { 6 | # Modules files list the scripts in the order they should be loaded 7 | $modules = Get-Content -Path "$($sPath)\$($group)\modules.txt" 8 | foreach ($module in $modules) 9 | { 10 | . "$($sPath)\$($group)\$($module)" 11 | } 12 | } -------------------------------------------------------------------------------- /backend/loadDialog.ps1: -------------------------------------------------------------------------------- 1 | function loadDialog 2 | { 3 | [xml]$Global:xmlWPF = $Xaml 4 | 5 | #Create the XAML reader using a new XML node reader 6 | $Global:xamGUI = [Windows.Markup.XamlReader]::Load((New-Object -TypeName System.Xml.XmlNodeReader -ArgumentList $xmlWPF)) 7 | 8 | #Create hooks to each named object in the XAML 9 | $xmlWPF.SelectNodes("//*[@Name]") | ForEach-Object { 10 | Set-Variable -Name ($_.Name) -Value $xamGUI.FindName($_.Name) -Scope Global 11 | } 12 | } -------------------------------------------------------------------------------- /launcher.ps1: -------------------------------------------------------------------------------- 1 | #Requires -Version 3 2 | param([switch]$debug) 3 | 4 | Add-Type -AssemblyName PresentationCore, PresentationFramework, WindowsBase 5 | 6 | $sPath = $PSScriptRoot 7 | 8 | . "$($sPath)\Mod-Loader.ps1" 9 | 10 | if ($debug) 11 | { 12 | Write-Host "DEBUG WINDOW" -ForegroundColor Cyan 13 | Write-Host "Do not close this window; report any errors that appear during testing" -ForegroundColor Cyan 14 | } 15 | else { Hide-Console } 16 | 17 | # Load and run program: 18 | MainProg 19 | 20 | Show-Console -------------------------------------------------------------------------------- /backend/Console-Controls.ps1: -------------------------------------------------------------------------------- 1 | Add-Type -Name Window -Namespace Console -MemberDefinition ' 2 | [DllImport("Kernel32.dll")] 3 | public static extern IntPtr GetConsoleWindow(); 4 | 5 | [DllImport("user32.dll")] 6 | public static extern bool ShowWindow(IntPtr hWnd, Int32 nCmdShow); 7 | ' 8 | 9 | function Show-Console 10 | { 11 | $console = [Console.Window]::GetConsoleWindow() 12 | [Console.Window]::ShowWindow($console, 5) | Out-Null 13 | } 14 | 15 | function Hide-Console 16 | { 17 | $console = [Console.Window]::GetConsoleWindow() 18 | [Console.Window]::ShowWindow($console, 0) | Out-Null 19 | } -------------------------------------------------------------------------------- /backend/Write-FormHost.ps1: -------------------------------------------------------------------------------- 1 | function Write-FormHost 2 | { 3 | [CmdletBinding()] 4 | param( 5 | [Parameter(Mandatory = $true, 6 | ValueFromPipeline = $true)] 7 | [string[]]$Text 8 | ) 9 | 10 | BEGIN { } 11 | 12 | PROCESS 13 | { 14 | foreach ($line in $Text) 15 | { 16 | # Render twice to account for interface lag 17 | $XamGUI.Dispatcher.Invoke( [action] {$textOutput.AddText("$($line)")}, "Render" ) 18 | $XamGUI.Dispatcher.Invoke( [action] {$textOutput.AddText("`n")}, "Render" ) 19 | } 20 | $textOutput.ScrollToEnd() 21 | } 22 | 23 | END { } 24 | } -------------------------------------------------------------------------------- /buttons/Help.ps1: -------------------------------------------------------------------------------- 1 | # Help Document 2 | $buttonHelpDocumentExp = 3 | { 4 | $HelpDoc = "$($sPath)\resources\Document.docx" 5 | if (Test-Path -Path $HelpDoc) 6 | { Invoke-Item -Path $HelpDoc } 7 | else 8 | { Show-Message -Title 'Help document not found' -Message "Help document '$($HelpDoc)' does not exist" } 9 | } 10 | 11 | # Changelog 12 | $buttonHelpLicenseExp = 13 | { 14 | $changelog = Get-Content -Path "$($sPath)\LICENSE" | Out-String 15 | Show-Message -Title "MIT License" -Message $changelog 16 | } 17 | 18 | # About 19 | $buttonHelpAboutExp = 20 | { 21 | $about = Get-Content -Path "$($sPath)\resources\about.txt" | Out-String 22 | Show-Message -Title 'About' -Message $about 23 | } -------------------------------------------------------------------------------- /buttons/SamplePage.ps1: -------------------------------------------------------------------------------- 1 | # Browse 2 | $buttonSPBrowseExp = 3 | { 4 | $dialog = [Microsoft.Win32.OpenFileDialog]::New() 5 | $dialog.DefaultExt = '.txt' 6 | $dialog.Filter = 'Text Files (*.txt)|*.txt' 7 | $result = $dialog.ShowDialog() 8 | if ($result) 9 | { $boxSPFileName.Text = $dialog.FileName } 10 | $boxSPFileName.Focus() 11 | } 12 | 13 | # Load 14 | $buttonSPLoadExp = 15 | { 16 | if ($boxSPFileName.Text -ne '') 17 | { 18 | $file = $boxSPFileName.Text 19 | $contents = Get-Content -Path $file 20 | 21 | foreach ($line in $contents) 22 | { 23 | if ($line -ne '') 24 | { Write-FormHost $line } 25 | else 26 | { Write-FormHost "`n" } 27 | } 28 | } 29 | } 30 | 31 | # Enter Action: 32 | $boxSPFileNameKeyDownExp = 33 | { 34 | if ( $args[1].Key -eq 'Return' ) 35 | { Invoke-Expression -Command "$($buttonSPLoadExp)" } 36 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Christopher R. Lowery (a.k.a.: The Powershell Bear) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /main/MainProg.ps1: -------------------------------------------------------------------------------- 1 | function MainProg 2 | { 3 | ### Load Main Form ### 4 | loadDialog 5 | 6 | ################### 7 | ### Wire Events ### 8 | ################### 9 | 10 | # Note: event actions are defined in buttons 11 | 12 | ################### 13 | ### Sample Page ### 14 | 15 | $buttonSPBrowse.add_Click( $buttonSPBrowseExp ) 16 | $buttonSPLoad.add_Click( $buttonSPLoadExp ) 17 | $boxSPFileName.add_KeyDown( $boxSPFileNameKeyDownExp ) 18 | 19 | ### ### 20 | ################### 21 | 22 | ################# 23 | ### Help Page ### 24 | 25 | $buttonHelpDocument.add_Click( $buttonHelpDocumentExp ) 26 | $buttonHelpLicense.add_Click( $buttonHelpLicenseExp ) 27 | $buttonHelpAbout.add_Click( $buttonHelpAboutExp ) 28 | 29 | ### ### 30 | ################# 31 | 32 | # Clear Output Button: 33 | $buttonClearOutput.add_Click({ $textOutput.Text = '' }) 34 | 35 | # Exit Button: 36 | $buttonExit.add_Click({ $xamGUI.Close() }) 37 | 38 | # Debug Button: 39 | $buttonDebug.add_Click( 40 | { 41 | Write-FormHost "Entering Debug Mode" 42 | Set-PSBreakpoint -Variable bugbreak -Mode Write 43 | $bugbreak = 1 44 | Get-PSBreakpoint -Variable bugbreak | Remove-PSBreakpoint -Confirm:$false 45 | $bugbreak = $null 46 | Write-FormHost "Exiting Debug Mode" 47 | }) 48 | 49 | if ($debug) 50 | { 51 | # Set all visible 52 | $buttonDebug.Visibility = 'Visible' 53 | } 54 | 55 | ### Launch the form ### 56 | $xamGUI.ShowDialog() | Out-Null 57 | } -------------------------------------------------------------------------------- /main/xaml-gui.xml.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | This contains the GUI in XAML format. 3 | Making changes here will modify the GUI: 4 | create new tabs, modify the layout, etc. 5 | #> 6 | 7 | [xml]$Xaml = @" 8 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 |