How to Create a GUI for PowerShell Scripts?

One of the significant drawbacks of PowerShell scripts, when used by users (not sysadmins or programmers), is its command-line interface. The result of the scripts is displayed in the PowerShell CLI console and it is not always convenient for the end user. However, Powershell is a powerful and modern automation tool for Windows that allows you to transparently use a variety of .NET Framework objects. For example, using the .NET API, you can easily create a simple graphical interface (GUI) for your PowerShell scripts.

In this example, we’ll show you how to create a simple Windows GUI form using PowerShell and place on it various standard Windows Forms controls elements: textboxes, buttons, labels, checkboxes/listboxes, radiobuttons, datagrids, etc. For example, our task is to build a simple GUI for a PowerShell script that shows the last password change time for the Active Directory user. In this example, we use PowerShell 3.0+ and PowerShell ISE for easy code editing.

Create Windows Form with PowerShell

To use the .NET functionality to create forms, we use the class System.Windows.Forms. To load this class into a PowerShell session, you can use the following code:

Add-Type -assembly System.Windows.Forms

Now create the screen form (window) to contain elements:

$main_form = New-Object System.Windows.Forms.Form

Set the title and size of the window:

$main_form.Text ='GUI for my PoSh script'

$main_form.Width = 600

$main_form.Height = 400

To make the form automatically stretch, if the elements on the form are out of window bounds, use the AutoSize property.

$main_form.AutoSize = $true

Now you can display the form on the screen.

$main_form.ShowDialog()

powershell gui

Adding Dialog-Box Components to your PowerShell Form

As you can see, an empty form was displayed. To add various graphical dialog and control elements to it, add the code below before the last line ($main_form.ShowDialog()).

Create a label element on the form:

$Label = New-Object System.Windows.Forms.Label

$Label.Text = "AD users"

$Label.Location  = New-Object System.Drawing.Point(0,10)

$Label.AutoSize = $true

$main_form.Controls.Add($Label)

Create a drop-down list and fill it with a list of accounts from the Active Directory domain. You can get AD user list using the Get-ADuser cmdlet (from Active Directory for Windows PowerShell module):

$ComboBox = New-Object System.Windows.Forms.ComboBox

$ComboBox.Width = 300

$Users = get-aduser -filter * -Properties SamAccountName

Foreach ($User in $Users)

{

$ComboBox.Items.Add($User.SamAccountName);

}

$ComboBox.Location  = New-Object System.Drawing.Point(60,10)

$main_form.Controls.Add($ComboBox)

Add two more labels to the form. The second will show the time of last password change for the selected user account:

$Label2 = New-Object System.Windows.Forms.Label

$Label2.Text = "Last Password Set:"

$Label2.Location  = New-Object System.Drawing.Point(0,40)

$Label2.AutoSize = $true

$main_form.Controls.Add($Label2)

$Label3 = New-Object System.Windows.Forms.Label

$Label3.Text = ""

$Label3.Location  = New-Object System.Drawing.Point(110,40)

$Label3.AutoSize = $true

$main_form.Controls.Add($Label3)

Now put the button on the form:

$Button = New-Object System.Windows.Forms.Button

$Button.Location = New-Object System.Drawing.Size(400,10)

$Button.Size = New-Object System.Drawing.Size(120,23)

$Button.Text = "Check"

$main_form.Controls.Add($Button)

The following code will be executed when the user clicks on the button. To convert the date from the TimeStamp format to the more convenient form, we use the function [datetime]::FromFileTime:

$Button.Add_Click(

{

$Label3.Text =  [datetime]::FromFileTime((Get-ADUser -identity $ComboBox.selectedItem -Properties pwdLastSet).pwdLastSet).ToString('MM dd yy : hh ss')

}

)

Run the PowerShell script. As you can see, the drop-down list is automatically filled with the names of the user accounts from Active Directory. If you select the user account and click the Check button, the form displays the time when the user’s last password was changed in Active Directory.

powershell gui builder

So you built your first simple graphical user interface for a PowerShell script. What’s next? Now you can add a more complex UI element to your PowerShell form.

Commonly Used PowerShell UI Elements

Similarly, you can create the following graphic elements on the form:

  • CheckBox – used to list some options and select them prior running script
  • RadioButton – lists some text options and allow to select only one of them;
  • TextBox – user can write some text. It can be used to get the vapue of the PoSh script parameter;
  • Label – used for labeling some parts of scripts’ GUI.
  • ChekedListBox – shows a list of items;
  • DataGridView – allows to view some tabular data;
  • GroupBox – allows to view to group a set of controls together;
  • ListBox – can store several text items;
  • TabControl – allows to split your form into different areas (tabs)
  • ListView – displays a list of items with text and (optionally) an icon
  • TreeView – hierarchical objects view;
  • DateTimePicker – allows to select date and time;
  • TrackBar – scrollable control;
  • PictureBox – allows to show picture on the form;
  • ProgressBar – indicates the operation progress
  • HScrollBar – horizontal scroll bar;
  • VScrollBar – vertical scroll bar;
  • ContextMenu – right click menus;
  • Menu – top menu in your form.

Building PowerShell Scripts’ GUI Using Visual Studio

You can use Visual Studio with a WPF (Windows Presentation Foundation) as a simple PowerShell GUI builder. Download and install Visual Studio Community 2019 version.

WPF is a part of the .NET Framework that can be used to visualize user interfaces in Windows apps.

Run Microsoft Visual Studio and create a new Project (File > New > Project). Select Visual C# > Windows Forms App (.NET Framework)

powershell gui examples

Use Windows Forms element in the left Toolbox pane to place (with drag&drop) your control element on the form.

powershell ui

The Visual Studio will generate an XAML code for you. Save this code into the file C:PSScriptMainWindow.xaml. Open this file using Notepad and remove the following string:

x:Class="test.MainWindow”

And save the changes in the xaml file.

Now you can read this XAML code from you PowerShell script and display a Windows Form.

Use the following function to load XAML object:

$XamlPath = “C:\PS\Script\MainWindow.xaml”

[xml]$Global:xmlWPF = Get-Content -Path $XamlPath

try{

Add-Type -AssemblyName PresentationCore,PresentationFramework,WindowsBase,system.windows.forms

} catch {

Throw "Failed to load WPF."

}

$Global:xamGUI = [Windows.Markup.XamlReader]::Load((new-object System.Xml.XmlNodeReader $xmlWPF))

$xmlWPF.SelectNodes("//*[@*[contains(translate(name(.),'n','N'),'Name')]]") | %{

Set-Variable -Name ($_.Name) -Value $xamGUI.FindName($_.Name) -Scope Global

}


To display your form use:

$xamGUI.ShowDialog()

Use the Online Editor to Create a Form for your PoSh Script

For more convenient creation of graphical elements for PowerShell forms, you can use the online editor to create a GUI form for PowerShell scripts: https://poshgui.com/Editor. With it, you can create a beautiful form with the necessary dialog elements.

powershell menu gui

And get the ready PoSh code for your GUI scripts. Just copy this code into your PowerShell ISE, change element names (optionally) and run the code to display the generated form on your computer.

gui powershell

Cyril Kardashevsky

5 comments

  1. This has been massively helpful – but I have a couple of questions

    I want to lookup all Security groups inside an OU and display that as a drop-down choice (done)
    I want to fetch 3 random usernames from within the selected security group – Help!

    With your tutorial I can output 1 of the usernames (below), but I can’t display 3.

    $Label3.Text = ((Get-ADGroupMember -Identity $ComboBox.selectedItem | select-object -Property Name, SamAccountName | Sort-Object{Get-Random} | select -first 3))

    Any ideas how I can get a text box to display 3 random usernames so I can copy/paste from the text box into an email?

    1. Dave, if you haven’t fixed this, I believe that further google searches can help you. I am no expert myself, but probably you should think in the ways of a looping function, that does the same thing three times if getting 3 results straight away doesn’t work.
      Also, why copy and paste? With PowerShell, you can send e-mails directly! Also, I only know that it can be done, just not how :-P
      Sorry for bad advice…

    2. I would recommend building the string and then trying to insert it.
      Your Get-AD call is returning 3 objects, loop through them and build the string then put the string in the value.

    3. The powershell command returns an array and that text field can only take the first piece.
      This should return a string out of the 3 member array :

      ((Get-ADGroupMember LeGroupName |select name,samaccountname | sort {Get-Random} |select -First 3) | % {$_.name+”`t”+$_.samaccountname}) -join “`r`n”

    4. Hi Dave,
      In relation to the email issue here is a quick and easy way to send the output of a command through email

      $output = ipconfig | out-string
      Send-MailMessage -From email@email.com -To whoneedsmorefreakinemails@email.com -Subject “Just show me the results already!!” -Body $output -Smtpserver smtp.email.com

      Obviously you will have to replace the email addresses and smtp server

      This can be run to store any command output as a variable and then add the variable(ie. command output) to the body of the email

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.