PowerShell GUI

PowerShell scriptign can be used to create graphical user interfaces quite easily.

No need to import specific modules or to purchase any external software, PowerShell works with WinForms out of the box.

.

1. GUI Step By Step

1.1 Interface Definition

To create a GUI using PowerShell, the first thing to do is to define properly the interface.

# Interface Definition
[void][System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
[void][System.Reflection.Assembly]::LoadWithPartialName("System.Drawing") 

.

Then, you can specify to hide the PowerShell Console in background.

# Hide PowerShell Console
Add-Type -Name Window -Namespace Console -MemberDefinition '
[DllImport("Kernel32.dll")]
public static extern IntPtr GetConsoleWindow();
[DllImport("user32.dll")]
public static extern bool ShowWindow(IntPtr hWnd, Int32 nCmdShow);
'
$consolePtr = [Console.Window]::GetConsoleWindow()
[Console.Window]::ShowWindow($consolePtr, 0) 

.

.

1.2 Main Form Definition

Define the main form (location, size, title…)

# Main Form Definition
$MainForm = New-Object System.Windows.Forms.Form
$MainForm.ClientSize = New-Object System.Drawing.Size(1000, 650)
$MainForm.MaximumSize = New-Object System.Drawing.Size(1000, 650)
$MainForm.MinimumSize = New-Object System.Drawing.Size(1000, 650)
$MainForm.MaximizeBox = $false
$MainForm.StartPosition = "CenterScreen"
$MainForm.Text = "PowerShell GUI Demo" 

.

.

1.3 Content

Now that the interface is defined and created, it’s time to put the content.

A lot of controls are available, each one with its own properties and specificities.

For example, we can add a Groupbox with a short description of what the script does by following these steps:

  • Creation of the Groupbox
  • Creation of the Label (which contains the text)
  • Assign the Label to the Groupbox
  • Assign the Groupbox to the Main Form
# GroupBox : Presentation
$Presentation_Groupbox = New-Object System.Windows.Forms.GroupBox
$Presentation_Groupbox.Location = New-Object System.Drawing.Point(10, 20)
$Presentation_Groupbox.Size = New-Object System.Drawing.Size(900, 110)
$Presentation_Groupbox.TabIndex = 0
$Presentation_Groupbox.TabStop = $false
$Presentation_Groupbox.Text = "Presentation"


# Presentation Text
$Presentation_Label = New-Object System.Windows.Forms.Label
$Presentation_Label.BorderStyle = [System.Windows.Forms.BorderStyle]::None
$Presentation_Label.Location = New-Object System.Drawing.Point(15, 15)
$Presentation_Label.Size = New-Object System.Drawing.Size(630, 90)
$Presentation_Label.Multiline = $true
$Presentation_Label.Text = " `r`nThis is a demo to illustrate PowerShell GUI article `r`n`r`n     1. Click the *Create Folder* button to create the folder C:\PS_GUI_Demo `r`n`r`n     2. Click the *Remove Folder* button to remove the folder"


# Assign Items to Groupbox
$Presentation_Groupbox.Controls.Add($Presentation_Label)


# Assign Groupbox to Form
$MainForm.Controls.Add($Presentation_Groupbox) 

.

And then we can add 2 buttons, allowing respectively to create a folder and to remove it:

  • Creation of a Groupbox (just for the cosmetic J)
  • Creation of the first Button (Create Folder)
  • Creation of the second Button (Remove Folder)
  • Assign the Buttons to the Groupbox
  • Assign the Groupbox to the Main Form
# GroupBox : Interactive Part (buttons)
$Interact_GroupBox = New-Object System.Windows.Forms.GroupBox
$Interact_GroupBox.Location = New-Object System.Drawing.Point(10, 180)
$Interact_GroupBox.Size = New-Object System.Drawing.Size(900, 110)
$Interact_GroupBox.TabIndex = 1
$Interact_GroupBox.TabStop = $false
$Interact_GroupBox.Text = "Select Action"


# "CREATE FOLDER" Button
$CreateFolder_Button = New-Object system.Windows.Forms.Button
$CreateFolder_Button.Text = "Create Folder"
$CreateFolder_Button.Location = New-Object System.Drawing.Size(50,40) 
$CreateFolder_Button.Size = New-Object System.Drawing.Size(300,40) 
$CreateFolder_Button.TabIndex = 0
$CreateFolder_Button.Add_Click({ CreateFolder }) 


# "REMOVE FOLDER" Button
$RemoveFolder_Button = New-Object system.Windows.Forms.Button
$RemoveFolder_Button.Text = "Remove Folder"
$RemoveFolder_Button.Location = New-Object System.Drawing.Size(550,40) 
$RemoveFolder_Button.Size = New-Object System.Drawing.Size(300,40) 
$RemoveFolder_Button.TabIndex = 1
$RemoveFolder_Button.Add_Click({ RemoveFolder }) 


# Assign Items to GroupBox
$Interact_GroupBox.Controls.Add($CreateFolder_Button)
$Interact_GroupBox.Controls.Add($RemoveFolder_Button)


# Assign GroupBox to Page
$MainForm.Controls.Add($Interact_GroupBox)

The “Add-Click” property allows to call a function when the button is clicked.

.

.

1.4 Functions

It’s now time to add the functions used to define the behavior of the script.

In our example, we have to add the functions CreateFolder and RemoveFolder which allows respectively to create and remove a folder by clicking the according button previously defined.

Function CreateFolder {
	If(!(Test-Path -Path "C:\PS_GUI_Demo")){
		New-Item -ItemType directory -Path "C:\PS_GUI_Demo"
	}
}


Function RemoveFolder {
	If(Test-Path -Path "C:\PS_GUI_Demo"){
		Remove-Item "C:\PS_GUI_Demo" -recurse
	}
} 

.

Don’t forget to create the Main function allowing to display the interface.

Function Main {
	[System.Windows.Forms.Application]::EnableVisualStyles()
	[System.Windows.Forms.Application]::Run($MainForm)
} 

.

.

1.5 Call the Main Function

The last step is to call the main function to display the interface:

Main

.

.

2. Controls

Here is a list of useful which can be used.

.

GroupBox

$GroupBox = New-Object System.Windows.Forms.GroupBox
$GroupBox.Location = New-Object System.Drawing.Point(10, 10)
$GroupBox.Size = New-Object System.Drawing.Size(400, 200)
$GroupBox.TabIndex = 0
$GroupBox.TabStop = $false
$GroupBox.Text = "GroupBox" 

.

Panel

$Panel = New-Object System.Windows.Forms.Panel
$Panel.Location = New-Object System.Drawing.Point(10, 20410
$Panel.Size = New-Object System.Drawing.Size(400, 200)
$Panel.TabIndex = 0
$Panel.BorderStyle = "FixedSingle" 
$Panel:AutoScroll = $true

.

Label

$Label = New-Object System.Windows.Forms.Label
$Label.BorderStyle = [System.Windows.Forms.BorderStyle]::None 
$Label.Location = New-Object System.Drawing.Point(10, 10)
$Label.Size = New-Object System.Drawing.Size(100, 20)
$Label.Multiline = $true 
$Label.TabIndex = 0
$Label.Text = "Label" 

.

Checkbox

$CheckBox = New-Object System.Windows.Forms.CheckBox
$CheckBox.Location = New-Object System.Drawing.Point(10, 10)
$CheckBox.Size = New-Object System.Drawing.Size(100, 20)
$CheckBox.TabIndex = 0
$CheckBox.Text = "CheckBox"
$CheckBox.UseVisualStyleBackColor = $true

.

Radio Button

$RadioButton = New-Object System.Windows.Forms.RadioButton
$RadioButton.Location = New-Object System.Drawing.Point(10, 10)
$RadioButton.Size = New-Object System.Drawing.Size(100, 20)
$RadioButton.TabIndex = 0
$RadioButton.TabStop = $true
$RadioButton.Text = "RadioButton"
$RadioButton.UseVisualStyleBackColor = $true 

.

ComboBox

$ComboBox = New-Object System.Windows.Forms.ComboBox
$ComboBox.DropDownStyle = [System.Windows.Forms.ComboBoxStyle]::DropDownList 
$ComboBox.FormattingEnabled = $true
$ComboBox.Location = New-Object System.Drawing.Point(10, 10)
$ComboBox.Size = New-Object System.Drawing.Size(100, 20)
$ComboBox.TabIndex = 0
$ComboBox.Text = ""
$ComboBox.Items.AddRange([System.Object[]](@("Option 1", "Option 2", "Option 3"))) 
$ComboBox.SelectedIndex = -1
$ComboBox.add_SelectedIndexChanged({MyFunction} 

.

TextBox

$TextBox = New-Object System.Windows.Forms.TextBox
$TextBox.BorderStyle = [System.Windows.Forms.BorderStyle]::None 
$TextBox.Location = New-Object System.Drawing.Point(10, 10)
$TextBox.Size = New-Object System.Drawing.Size(100, 20)
$TextBox.TabIndex = 0
$TextBox.Text = "Text" 

.

PictureBox

$PictureBox = New-Object System.Windows.Forms.PictureBox
$PictureBox.Location = New-Object System.Drawing.Point(10, 10)
$PictureBox.Size = New-Object System.Drawing.Size(400, 400)
$PictureBox.TabIndex = 0
$PictureBox.Image = "C:\MyPath\MyPicture.png"

.

Button

$Button = New-Object System.Windows.Forms.Button
$Button.Location = New-Object System.Drawing.Point(10, 10)
$Button.Size = New-Object System.Drawing.Size(100, 20)
$Button.TabIndex = 0
$Button.Text = "Button"
$Button.UseVisualStyleBackColor = $true 
$Button.Add_Click({ MyFunction })  

.

DateTimePicker

$DateTimePicker1 = New-Object System.Windows.Forms.DateTimePicker
$DateTimePicker1.Location = New-Object System.Drawing.Point(10, 10)
$DateTimePicker1.Size = New-Object System.Drawing.Size(200, 20)
$DateTimePicker1.TabIndex = 0

.

.

3. Demo

#=================================================================================================================================
# POWERSHELL GUI DEMO
#=================================================================================================================================
# Date    : 04.2017
# Version : 1.0
# Author  : Damdbs
#=================================================================================================================================
# This script is a demo to illustrate the documentation about PowerShell GUI
#=================================================================================================================================



##*=============================================================================================================================================
##* DEFINITIONS
##*=============================================================================================================================================

# Interface Definition
[void][System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
[void][System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")

# Script Directory Definition
# Set the variable $scriptDirectory with the path from where the script is run
If (Test-Path -LiteralPath 'variable:HostInvocation') { $InvocationInfo = $HostInvocation } Else { $InvocationInfo = $MyInvocation }
[string]$scriptDirectory = Split-Path -Path $InvocationInfo.MyCommand.Definition -Parent

# Hide PowerShell Console
Add-Type -Name Window -Namespace Console -MemberDefinition '
[DllImport("Kernel32.dll")]
public static extern IntPtr GetConsoleWindow();
[DllImport("user32.dll")]
public static extern bool ShowWindow(IntPtr hWnd, Int32 nCmdShow);
'
$consolePtr = [Console.Window]::GetConsoleWindow()
[Console.Window]::ShowWindow($consolePtr, 0)



##*=============================================================================================================================================
##* MAIN FORM
##*=============================================================================================================================================

# Main Form Definition
$MainForm = New-Object System.Windows.Forms.Form
$MainForm.ClientSize = New-Object System.Drawing.Size(1000, 650)
$MainForm.MaximumSize = New-Object System.Drawing.Size(1000, 650)
$MainForm.MinimumSize = New-Object System.Drawing.Size(1000, 650)
$MainForm.MaximizeBox = $false
$MainForm.StartPosition = "CenterScreen"
$MainForm.Text = "PowerShell GUI Demo"



##*=============================================================================================================================================
##* PRESENTATION
##*=============================================================================================================================================

# GroupBox : Presentation
$Presentation_Groupbox = New-Object System.Windows.Forms.GroupBox
$Presentation_Groupbox.Location = New-Object System.Drawing.Point(10, 20)
$Presentation_Groupbox.Size = New-Object System.Drawing.Size(900, 110)
$Presentation_Groupbox.TabIndex = 0
$Presentation_Groupbox.TabStop = $false
$Presentation_Groupbox.Text = "Presentation"

# Presentation Text
$Presentation_Label = New-Object System.Windows.Forms.Label
$Presentation_Label.BorderStyle = [System.Windows.Forms.BorderStyle]::None
$Presentation_Label.Location = New-Object System.Drawing.Point(15, 15)
$Presentation_Label.Size = New-Object System.Drawing.Size(630, 90)
$Presentation_Label.Multiline = $true
$Presentation_Label.Text = " `r`nThis is a demo to illustrate PowerShell GUI article `r`n`r`n     1. Click the *Create Folder* button to create the folder C:\PS_GUI_Demo `r`n`r`n     2. Click the *Remove Folder* button to remove the folder"

# Assign Items to Groupbox
$Presentation_Groupbox.Controls.Add($Presentation_Label)

# Assign Groupbox to Form
$MainForm.Controls.Add($Presentation_Groupbox)



##*=============================================================================================================================================
##* INTERACTIVE PART (BUTTONS)
##*=============================================================================================================================================

# GroupBox : Interactive Part (buttons)
$Interact_GroupBox = New-Object System.Windows.Forms.GroupBox
$Interact_GroupBox.Location = New-Object System.Drawing.Point(10, 180)
$Interact_GroupBox.Size = New-Object System.Drawing.Size(900, 110)
$Interact_GroupBox.TabIndex = 1
$Interact_GroupBox.TabStop = $false
$Interact_GroupBox.Text = "Select Action"

# "CREATE FOLDER" Button
$CreateFolder_Button = New-Object system.Windows.Forms.Button
$CreateFolder_Button.Text = "Create Folder"
$CreateFolder_Button.Location = New-Object System.Drawing.Size(50,40) 
$CreateFolder_Button.Size = New-Object System.Drawing.Size(300,40) 
$CreateFolder_Button.TabIndex = 0
$CreateFolder_Button.Add_Click({ CreateFolder }) 

# "REMOVE FOLDER" Button
$RemoveFolder_Button = New-Object system.Windows.Forms.Button
$RemoveFolder_Button.Text = "Remove Folder"
$RemoveFolder_Button.Location = New-Object System.Drawing.Size(550,40) 
$RemoveFolder_Button.Size = New-Object System.Drawing.Size(300,40) 
$RemoveFolder_Button.TabIndex = 1
$RemoveFolder_Button.Add_Click({ RemoveFolder }) 

# Assign Items to GroupBox
$Interact_GroupBox.Controls.Add($CreateFolder_Button)
$Interact_GroupBox.Controls.Add($RemoveFolder_Button)

# Assign GroupBox to Page
$MainForm.Controls.Add($Interact_GroupBox)



##*=============================================================================================================================================
##* OUTPUT BOX
##*=============================================================================================================================================

# GroupBox : Output Box
$Outbox_GroupBox = New-Object System.Windows.Forms.GroupBox
$Outbox_GroupBox.Location = New-Object System.Drawing.Point(10, 340)
$Outbox_GroupBox.Size = New-Object System.Drawing.Size(900, 260)
$Outbox_GroupBox.TabIndex = 2
$Outbox_GroupBox.TabStop = $false
$Outbox_GroupBox.Text = "Log"

# OutputBox
$Outbox_TextBox = New-Object System.Windows.Forms.TextBox
$Outbox_TextBox.Location = New-Object System.Drawing.Point(20, 20)
$Outbox_TextBox.Size = New-Object System.Drawing.Size(865, 220)
$Outbox_TextBox.TabIndex = 0
$Outbox_TextBox.Text = "***History of actions ***"
$Outbox_TextBox.MultiLine = $True
$Outbox_TextBox.WordWrap = $False
$Outbox_TextBox.ScrollBars = "Both"

# Assign Items to GroupBox 2
$Outbox_GroupBox.Controls.Add($Outbox_TextBox)

# Assign GroupBox 3 to Page
$MainForm.Controls.Add($Outbox_GroupBox)



##*=============================================================================================================================================
##* FUNCTIONS
##*=============================================================================================================================================

Function Main {
	[System.Windows.Forms.Application]::EnableVisualStyles()
	[System.Windows.Forms.Application]::Run($MainForm)
}

Function CreateFolder {
	$Outbox_TextBox.Text = $Outbox_TextBox.Text + "`r`n`r`n*Create Folder* button clicked..."
	If(!(Test-Path -Path "C:\PS_GUI_Demo" )){
		New-Item -ItemType directory -Path "C:\PS_GUI_Demo"
		$Outbox_TextBox.Text = $Outbox_TextBox.Text + "`r`nThe folder *C:\PS_GUI_Demo* has been created successfully"
	}
	Else {
		$Outbox_TextBox.Text = $Outbox_TextBox.Text + "`r`nThe folder *C:\PS_GUI_Demo* already exist"
	}
}

Function RemoveFolder {
	$Outbox_TextBox.Text = $Outbox_TextBox.Text + "`r`n`r`n*Remove Folder* button clicked..."
	If(!(Test-Path -Path "C:\PS_GUI_Demo" )){
		$Outbox_TextBox.Text = $Outbox_TextBox.Text + "`r`nThe folder *C:\PS_GUI_Demo* does not exist"
	}
	Else {
		Remove-Item "C:\PS_GUI_Demo" -recurse
		$Outbox_TextBox.Text = $Outbox_TextBox.Text + "`r`nThe folder *C:\PS_GUI_Demo* has been removed successfully"
	}
}



##*=============================================================================================================================================
##* CALL MAIN FUNCTION
##*=============================================================================================================================================

Main
 

.