PowerShell GUI to install selected software

I am currently using a batch file to silently install multiple software, after the fresh installation of Windows. I simply double-click the batch file and everything is installed silently without any prompts.

Using PowerShell, I want to create a simple GUI showing the list of software with check-boxes next to them, so someone can select the software the want to install, click the “Install” button and their selections will be installed.

I have some PowerShell experience with scripting and automation, but nothing with creating a GUI.

If I can have an example of how to do this, it would get me started and I could create my list.

 

Thanks

This could be a good starting point for you:

https://foxdeploy.com/2015/04/10/part-i-creating-powershell-guis-in-minutes-using-visual-studio-a-new-hope/

Another idea would be to use a “text menu” in a normal Powershell console window.

I have this, but I’m doing something wrong because when I run the script, the installation starts immediately. Whereas I should select, click ok, and the the installation should start.

 

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

# set form size
$Form = New-Object System.Windows.Forms.Form
$Form.width = 500
$Form.height = 500
$Form.Text = ”Install Software”

# set font
$Font = New-Object System.Drawing.Font("Verdana",10)
$Form.Font = $Font

# 7-zip checkbox 
$checkbox1 = new-object System.Windows.Forms.checkbox
$checkbox1.Location = new-object System.Drawing.Size(30,30)
$checkbox1.Size = new-object System.Drawing.Size(250,50)
$checkbox1.Text = " 7-Zip"
$checkbox1.Checked = $false
$Form.Controls.Add($checkbox1) 

# ok button
$OKButton = new-object System.Windows.Forms.Button
$OKButton.Location = new-object System.Drawing.Size(130,400)
$OKButton.Size = new-object System.Drawing.Size(100,40)
$OKButton.Text = "OK"
$OKButton.Add_Click({$Form.Close()})
$form.Controls.Add($OKButton)

# cancel button
$CancelButton = new-object System.Windows.Forms.Button
$CancelButton.Location = new-object System.Drawing.Size(255,400)
$CancelButton.Size = new-object System.Drawing.Size(100,40)
$CancelButton.Text = "Cancel"
$CancelButton.Add_Click({$Form.Close()})
$form.Controls.Add($CancelButton)

$checkbox1.Add_CheckStateChanged({
$OKButton.Enabled = $checkbox1.Checked })

If ($checkbox1.Checked = $true) { C:\software\7z1900-x64.exe }

# Activate the form
$Form.Add_Shown({$Form.Activate()})
[void] $Form.ShowDialog()

When do you want to invoke the installation?
Is it at the checkbox checked state or while clicking the OK button?

If it is checked state, below code should go within the checked state change event of the checkbox and it will be a good idea if you disable the checkbox once checked. Otherwise, your end users may trigger multiple instances of installations.
[PRE]
If ($checkbox1.Checked = $true) { C:\software\7z1900-x64.exe }
[/PRE]

If it is while clicking the OK button then it should go within the click event of OK button.

The idea is that you select all the software you want to install, and then you click OK. At which point the software you selected, start installing one by one.

Add a click event to the OK button, then check the checked status of each checkbox. If the checked status is true, then use the start-process cmdlet with -wait switch. This will trigger the installation one at a time.
Your GUI will go freeze until everything finishes.
[PRE]
$OKButton.Add_Click({
If ($checkbox1.Checked = $true)
{
Start-Process -FilePath ‘C:\software\7z1900-x64.exe’ -Wait

}
If ($checkbox2.Checked = $true) 
{ 
    Start-Process -FilePath 'C:\software\anotherSoftware.exe' -Wait
    
}
$Form.Close()

})
[/PRE]

Before testing, go through the documentation of start-process cmdlet to leverage the required parameters of your choice

Thanks for the information. You’re right, it worked.

How can I handle the GUI getting stuck though?

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

# set form size
$Form = New-Object System.Windows.Forms.Form
$Form.width = 500
$Form.height = 500
$Form.Text = ”Install Software”

# set font
$Font = New-Object System.Drawing.Font("Verdana",10)
$Form.Font = $Font

# checkbox 7-zip
$checkbox1 = new-object System.Windows.Forms.checkbox
$checkbox1.Location = new-object System.Drawing.Size(30,30)
$checkbox1.Size = new-object System.Drawing.Size(120,20)
$checkbox1.Text = " 7-Zip"
$checkbox1.Checked = $false
$Form.Controls.Add($checkbox1)

# checkbox notepad ++
$checkbox2 = new-object System.Windows.Forms.checkbox
$checkbox2.Location = new-object System.Drawing.Size(30,50)
$checkbox2.Size = new-object System.Drawing.Size(120,20)
$checkbox2.Text = " Notepad ++"
$checkbox2.Checked = $false
$Form.Controls.Add($checkbox2)

# ok button
$OKButton = new-object System.Windows.Forms.Button
$OKButton.Location = new-object System.Drawing.Size(130,400)
$OKButton.Size = new-object System.Drawing.Size(100,40)
$OKButton.Text = "OK"
$OKButton.Add_Click({$Form.Close()})
$form.Controls.Add($OKButton)

# cancel button
$CancelButton = new-object System.Windows.Forms.Button
$CancelButton.Location = new-object System.Drawing.Size(255,400)
$CancelButton.Size = new-object System.Drawing.Size(100,40)
$CancelButton.Text = "Cancel"
$CancelButton.Add_Click({$Form.Close()})
$form.Controls.Add($CancelButton)


$OKButton.Add_Click{

if($checkbox1.Checked) {Start-Process -FilePath C:\software\7z1900-x64.exe /S}
if($checkbox2.Checked) {Start-Process -FilePath C:\software\npp.7.8.1.Installer.x64.exe /S}

}

# activate form
$Form.Add_Shown({$Form.Activate()})
[void] $Form.ShowDialog()

Actually the click event script block waits until evrything finishes then release the control back to form, so yor GUI goes to unresponsive state.

One of my scenario, I gathered all the commands and it’s arguments to a script block, in your case the exe files and may be their switces. Then I started a new powershell process within the click event and passed that script block as an argument, so another powershell window opened and task started in that window. Then closes the GUI. The new window will automatically closes once done with all of my activities.

Also you could start that script block as a JOB within powrshell so that it runs in the background.