From ff38537262901ca3802babf945097c2087898471 Mon Sep 17 00:00:00 2001 From: mlot Date: Thu, 15 Jan 2026 11:17:53 -0500 Subject: [PATCH] initial commit --- Hello_World.png | Bin 0 -> 4902 bytes LICENSE | 9 ++ PSGUIFunctions.ps1 | 210 +++++++++++++++++++++++++++++++++++++++++++++ README.md | 70 +++++++++++++++ 4 files changed, 289 insertions(+) create mode 100644 Hello_World.png create mode 100644 LICENSE create mode 100644 PSGUIFunctions.ps1 create mode 100644 README.md diff --git a/Hello_World.png b/Hello_World.png new file mode 100644 index 0000000000000000000000000000000000000000..f7c381c12963c61ca7b15c7504748f341b0b1488 GIT binary patch literal 4902 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 literal 0 HcmV?d00001 diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..3092bfd --- /dev/null +++ b/LICENSE @@ -0,0 +1,9 @@ +MIT License + +Copyright (c) 2025 mlot + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/PSGUIFunctions.ps1 b/PSGUIFunctions.ps1 new file mode 100644 index 0000000..9363d34 --- /dev/null +++ b/PSGUIFunctions.ps1 @@ -0,0 +1,210 @@ +#Requires -Version 5 + +# Collection of cobbled together Powershell functions for GUI based message and user input prompts. + +function Select-Folder { + <# + .SYNOPSIS + Opens a folder selection dialog and returns full path to the folder. + + .EXAMPLE + $selectedFolder = Select-Folder + #> + Add-Type -AssemblyName System.Windows.Forms + $FolderSelect = New-Object System.Windows.Forms.FolderBrowserDialog + $null = $FolderSelect.ShowDialog() + $SelectedFolder = $FolderSelect.SelectedPath + return $SelectedFolder +} + + +function Select-File { + <# + .SYNOPSIS + Opens a file selection dialog and returns full path to the file. + + .PARAMETER InitialDialogDir + Specifies the inital directory to start in the dialog. If unspecified it defaults to the root of the home drive. + + .EXAMPLE + $selectedFile = Select-File -InitialDialogDir "C:\Users\Public\Documents" + #> + param ( + [Parameter(Mandatory=$false)] + [String] $InitialDialogDir = "$env:HOMEDRIVE" + ) + Add-Type -AssemblyName System.Windows.Forms + $FileSelect = New-Object System.Windows.Forms.OpenFileDialog -Property @{ + InitialDirectory = $InitialDialogDir + filter = "All files (*.*)| *.*" + } + $null = $FileSelect.ShowDialog() + $SelectedFile = $FileSelect.FileName + return $SelectedFile +} + + +function Save-File { + <# + .SYNOPSIS + Creates a save file dialog and returns the path and name of the file to save. + + .PARAMETER InitialDialogDir + Specifies the initial directory to start in the dialog. If unspecified it defaults to the root of the home drive. + + .EXAMPLE + $saveFile = Save-File -InitialDialogDir "C:\Users\Public\Documents" + #> + param ( + [Parameter(Mandatory=$false)] + [String] + $InitialDialogDir = "$env:HOMEDRIVE" + ) + Add-Type -AssemblyName System.Windows.Forms + $FileSelect = New-Object System.Windows.Forms.SaveFileDialog -Property @{ + InitialDirectory = $InitialDialogDir + filter = "All files (*.*)| *.*" + } + $null = $FileSelect.ShowDialog() + $SelectedFile = $FileSelect.FileName + return $SelectedFile +} + + +function Show-MessageBox { + <# + .SYNOPSIS + Displays a message box and returns the button pressed in response. + + .PARAMETER MessageText + Specifies the main text of the message to display. + + .PARAMETER MessageTitle + Specifies the title of the message box. + + .PARAMETER ButtonOptions + Specifies the button types shown for response to the message box. Default is 'OKCancel'. + + .PARAMETER MessageBoxIcon + Specifies the icon displayed on the message box to indicate it's type. Default is 'Information'. + + .PARAMETER MessageBoxDefaultButton + Specifies the default button to be activated on the message box. Default is 'Button1'. + + .EXAMPLE + $returnedMessageBoxButton = Show-MessageBox -MessageText "Hello, World" -MessageTitle "Hello World" + #> + param ( + [Parameter(Mandatory=$true)] + [String] + $MessageText, + [Parameter(Mandatory=$false)] + [String] + $MessageTitle = "Message", + [Parameter(Mandatory=$false)] + [String] + $ButtonOptions = "OKCancel", # YesNoCancel, AbortRetryIgnore, YesNo, RetryCancel + [Parameter(Mandatory=$false)] + [String] + $MessageBoxIcon = "Information", # Error, Question, Warning, Stop, Hand + [Parameter(Mandatory=$false)] + [String] + $MessageBoxDefaultButton = "Button1" # Button2, Button3 + ) + Add-Type -AssemblyName System.Windows.Forms + $ButtonReturn=[System.Windows.Forms.MessageBox]::Show("$MessageText","$MessageTitle", + + [System.Windows.Forms.MessageBoxButtons]::$ButtonOptions,[System.Windows.Forms.MessageBoxIcon]::$MessageBoxIcon, + + [System.Windows.Forms.MessageBoxDefaultButton]::$MessageBoxDefaultButton) + return $ButtonReturn +} + + +function Get-UserInput { + <# + .SYNOPSIS + Displays a user input box and returns the user's input as a string (default) or integer (see parameter). + + .PARAMETER InputMessage + Specifies the main text of the input box message to display. + + .PARAMETER InputTitle + Specifies the title of the input box. + + .PARAMETER DefaultInput + Allows you to set an initial default input value for the user. + + .PARAMETER ReturnAsInteger + Default is set to '$false'. Set to '$true' to convert input from string to integer (if conversion is possible). + + .EXAMPLE + $userInput = Get-UserInput -InputMessage "What is your name?" -InputTitle "Your Information" + $userInput = Get-UserInput -InputMessage "How old are you?" -ReturnAsInteger $true + #> + param ( + [Parameter(Mandatory=$true)] + [String] + $InputMessage, + [Parameter(Mandatory=$false)] + [String] + $InputTitle = "Input Request", + [Parameter(Mandatory=$false)] + [String] + $DefaultInput, + [Parameter(Mandatory=$false)] + [bool] + $ReturnAsInteger = $false # Set to "$true" if you want a numeric string converted to an integer + ) + [void][System.Reflection.Assembly]::LoadWithPartialName('Microsoft.VisualBasic') + $UsersInput = [Microsoft.VisualBasic.Interaction]::InputBox($InputMessage, $InputTitle, $DefaultInput) + if ($ReturnAsInteger -eq $true -and $UsersInput -match "^\d+$") { + return [int]$UsersInput + } else { + return $UsersInput + } +} + + +# Display Listbox Input Selection +function Show-ListBox { + <# + .SYNOPSIS + Displays a listbox and returns single or multiple choices from the list of items. (Uses Powershell's Out-GridView.) + + .PARAMETER ItemsForList + List items must be passed in from a Powershell array. + + .PARAMETER ChoiceMode + Allows you to set for 'Single' item only or 'Multiple' item selections by user. Default is 'Single'. + Single items are returned as System.String type, multiple items are returned as a System.Object[] type. + + .PARAMETER BoxTitle + Specifies the title of the list box and can be used to ask for selection. + + .PARAMETER SortListItems + Allows you to specify if list item are sorted (e.g. alphabetically). Default is '$false'. + + .EXAMPLE + $listItems = @('Jack','John','Jill','Jane') + $userInput = Show-ListBox -ItemsForList $listItems -BoxTitle "Please choose a name:" -ChoiceMode "Single" -SortListItems $true + #> + param ( + [Parameter(Mandatory=$true)] + [array] + $ItemsForList, # List items passed in as an array + [Parameter(Mandatory=$false)] + [String] + $ChoiceMode = "Single", # "Single" (default) or "Multiple" item selection + [Parameter(Mandatory=$false)] + [String] + $BoxTitle = "Choose item below and press OK:", + [Parameter(Mandatory=$false)] + [bool] + $SortListItems = $false # Set to "$true" if you want to sort the list items alphanumerically + ) + if ($SortListItems) { + $SelectedBoxItems = $ItemsForList | Sort-Object | Out-GridView -OutputMode $ChoiceMode -Title $BoxTitle + } else { + $SelectedBoxItems = $ItemsForList | Out-GridView -OutputMode $ChoiceMode -Title $BoxTitle + } + return $SelectedBoxItems +} diff --git a/README.md b/README.md new file mode 100644 index 0000000..efa1f97 --- /dev/null +++ b/README.md @@ -0,0 +1,70 @@ +[![Language](https://img.shields.io/badge/language-powershell-blue.svg)](https://docs.microsoft.com/en-us/powershell/) + +# PSGUIFunctions +A small collection of cobbled together Powershell functions for GUI messages and user input. + +## Purpose and Background +I just needed a simple and easy way to display information, warnings, get input, select a file or directory, or ask a simple response question in a GUI format for my Powershell scripts. Sure there are many great modules I could use that are much more sophisticated, but I just found it fun to make my own and only needed some basic options. That's why I pieced together PSGUIFunction's examples for input and dialog boxes. Hopefully, you can get some use from them too. + +**The message boxes available are:** +* Information +* Warning +* Error +* Question +* Yes/No +* Ok/Cancel +* Retry/Cancel +* Abort/Retry/Ignore + +**The input boxes available are:** +* String/Integer Input Box (returns a string or integer if entered) +* Listbox Input (returns the selection(s) from a given array) + +**The dialog boxes available are:** +* Select Filename (returns full path to file selected) +* Save As Filename (returns full path to file and name for saving) +* Select Directory (returns full path to directory selected) + +![Example Image](https://tildeforge.dev/mlot/PSGUIFunctions/raw/branch/main/Hello_World.png "Example Image") + +## Requirements +* [ ] Windows Powershell 5.1 and/or Powershell Core 7 + +Tested with Windows 11 x64 Version 23H2 + +## Installation +No install required. Just copy and paste the examples from within the PSGUIFunctions.ps1 file directly into your own script and modify as needed. + +Downloading PSGUIFunctions.ps1 using [cURL](https://curl.haxx.se/): + +``` +curl -o PSGUIFunctions.ps1 https://tildeforge.dev/mlot/PSGUIFunctions/raw/branch/main/PSGUIFunctions.ps1 +``` + +## Example Use + +Copy and paste the function examples from within the PSGUIFunctions.ps1 file directly into your own script and call the function passing the required or optional arguments: +```powershell +function Select-Folder { + <# + .SYNOPSIS + Opens a folder selection dialog and returns full path to the folder. + + .EXAMPLE + $selectedFolder = Select-Folder + #> + Add-Type -AssemblyName System.Windows.Forms + $FolderSelect = New-Object System.Windows.Forms.FolderBrowserDialog + $null = $FolderSelect.ShowDialog() + $SelectedFolder = $FolderSelect.SelectedPath + return $SelectedFolder +} + +$selectedFolder = Select-Folder # Returns the full path to the selected folder assigning it to the $selectedFolder variable +``` + +## Contributing +If you want to contribute new functions or improve the exisiting ones, feel free to clone the repo and submit a pull request. And thanks for any time and help! + +## License +[MIT License](https://opensource.org/licenses/MIT) for PSGUIFunctions