Dynamic Form Checking Checkboxes on Click

I have created a dynamic form that push it variables out of a text file. The for displays correctly but once I click the submit button I am unable to check if the checkboxes have been checked.

$scriptpath = $MyInvocation.MyCommand.Path
$dir = Split-Path $scriptpath

$temp = "C:\Temp\install_onclick.txt"
if ($temp) {
	Clear-Content $temp	
}

$software = Import-CSV -Path "$dir\Test\software.txt"
$software | Measure-Object | Out-Null

$count = $software.Count

# Start Form Build
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing

# Form Layout Variables
$form = New-Object system.Windows.Forms.Form
$form.Text = "Software Install v2.0" # Form Title
$form.Height = 250
$form.Width = 350

$i = 0
ForEach ($app in $software) {
	$dycheck = "`$Install" + $app.Shortname
	$dycheck = New-Object system.Windows.Forms.CheckBox
	$dycheck.Text = $app.FriendlyName
	$dycheck.Name = "`Install" + $app.ShortName
	$i++
	$y = $i * 20
	$dycheck.Location = New-Object System.Drawing.Size(20, $y)
	$dycheck.Size = New-Object System.Drawing.Size(145, 20)
	$form.Controls.Add($dycheck)
	$dycheck | Out-File $temp -Append
}

$pcoutput = New-Object System.Windows.Forms.TextBox
$pcoutput.MultiLine = $True
$pcoutput.ReadOnly = $True
$pcoutput.BackColor = "White"
$pcoutput.ScrollBars = "Vertical"
$pcoutput.Size = New-Object System.Drawing.Size(155, 200)
$pcoutput.Location = New-Object System.Drawing.Size(156, 5)
$pcoutput.Text = "Idle ...`r`n"
$form.Controls.Add($pcoutput)

$install_Onclick = {
	ForEach ($app in $software) {
		$dycheck = "`$Install" + $app.Shortname
		if ($dycheck.Checked) {
			$name = $app.FriendlyName
			$pcoutput.AppendText("Installing `$name ...`r`n")
		}
		else {
			Get-Variable $dycheck
			$pcoutput.AppendText("Not Checked $name ...`r`n")
		}
	}
}

# Install Button begins the installation proces based on checkboxes checked.
$installButton = New-Object System.Windows.Forms.Button
$installButton.Name = "installButton"
$installButton.Text = "Install"
$installButton.Location = New-Object System.Drawing.Size(5, 175)
$installButton.add_Click($install_Onclick)
$form.Controls.Add($installButton)

$form.ShowDialog()

$install_Click is the part I am having issues with. I have tried numerous ways of writing this and have hit a brick wall. Any help is appreciated.

Try this. Powershell doesn’t really like doing dynamic variables, especially with checkboxes, etc… So what I did is create a new variable using the text (you don’t need to use $ when creating or doing get-variable), so I was able to use (get-variable).value.XXX where XXX is the values you care about. When accessing the variable directly, you could do $InstallWinZip.checked But because ‘InstallWinzip’ is a dynamic variable you’re combining strings to produce… .I used the get-variable command… and it’s further inside the object hidden under .value

$InstallWinZip.checked is equal to (get-variable InstallWinzip).value.checked

I changed all references to your dynamic stuff to follow this pattern. Also… in the OnClick section, I moved the $Name = $app.FriendlyName up out of the IF statement. Before, it would only generate the $Name variable if it was checked… so it’d use the same name for all of them… based on whichever was the last checked prior to the one that wasn’t. hope that makes sense.

$scriptpath = $MyInvocation.MyCommand.Path
$dir = Split-Path $scriptpath

$temp = "C:\Temp\install_onclick.txt"
if ($temp) {
	Clear-Content $temp	
}

$software = Import-CSV -Path "$dir\Test\software.txt"
$software | Measure-Object | Out-Null

$count = $software.Count

# Start Form Build
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing

# Form Layout Variables
$form = New-Object system.Windows.Forms.Form
$form.Text = "Software Install v2.0" # Form Title
$form.Height = 250
$form.Width = 350

$i = 0
ForEach ($app in $software) {

    $VariableName = "Install" + $app.ShortName
    "Creating $VariableName"
    New-Variable -Name $VariableName -Value (new-object system.windows.forms.checkbox) -Force
#	$form.Controls.Add((get-variable $VariableName))
	$form.Controls.Add((get-variable $VariableName).Value)
	(get-variable $VariableName).value.Text = $app.FriendlyName
	$i++
	$y = $i * 20
	(get-variable $VariableName).value.Location = New-Object System.Drawing.Size(20, $y)
	(get-variable $VariableName).value.Size = New-Object System.Drawing.Size(145, 20)

    #### Not sure what this line was doing, so i disabled it)
	#$dycheck | Out-File $temp -Append
}

$pcoutput = New-Object System.Windows.Forms.TextBox
$pcoutput.MultiLine = $True
$pcoutput.ReadOnly = $True
$pcoutput.BackColor = "White"
$pcoutput.ScrollBars = "Vertical"
$pcoutput.Size = New-Object System.Drawing.Size(155, 200)
$pcoutput.Location = New-Object System.Drawing.Size(156, 5)
$pcoutput.Text = "Idle ...`r`n"
$form.Controls.Add($pcoutput)

$install_Onclick = {
	ForEach ($app in $software) {
        $name = $app.FriendlyName
		if ((get-variable ("Install" + $app.Shortname)).value.Checked) {
			
			$pcoutput.AppendText("Installing $name ...`r`n")
		}
		else {
			(get-variable ("Install" + $app.Shortname)).value
			$pcoutput.AppendText("Not Checked $name ...`r`n")
		}
	}
}

# Install Button begins the installation process based on checkboxes checked.
$installButton = New-Object System.Windows.Forms.Button
$installButton.Name = "installButton"
$installButton.Text = "Install"
$installButton.Location = New-Object System.Drawing.Size(5, 175)
$installButton.add_Click($install_Onclick)
$form.Controls.Add($installButton)

$form.ShowDialog()

for your check of your variable dycheck in the Else statement ommit the $

see if this helps I added this:
if (($form.Controls | ?{$_.name -eq $dycheck.trim(‘$’)}).checked)

basically getting the form object that has the value you want being checked or unchecked in the form object.

$scriptpath = $MyInvocation.MyCommand.Path
$dir = Split-Path $scriptpath

$temp = "C:\Temp\install_onclick.txt"
if ($temp)
{
	Clear-Content $temp
}

$software = Import-CSV -Path "$dir\Test\software.txt"
$software | Measure-Object | Out-Null

$count = $software.Count

# Start Form Build
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing

# Form Layout Variables
$form = New-Object system.Windows.Forms.Form
$form.Text = "Software Install v2.0" # Form Title
$form.Height = 250
$form.Width = 350

$i = 0
ForEach ($app in $software)
{
	$dycheck = "`$Install" + $app.Shortname
	$dycheck = New-Object system.Windows.Forms.CheckBox
	$dycheck.Text = $app.FriendlyName
	$dycheck.Name = "`Install" + $app.ShortName
	$i++
	$y = $i * 20
	$dycheck.Location = New-Object System.Drawing.Size(20, $y)
	$dycheck.Size = New-Object System.Drawing.Size(145, 20)
	$form.Controls.Add($dycheck)
	$dycheck | Out-File $temp -Append
}

$pcoutput = New-Object System.Windows.Forms.TextBox
$pcoutput.MultiLine = $True
$pcoutput.ReadOnly = $True
$pcoutput.BackColor = "White"
$pcoutput.ScrollBars = "Vertical"
$pcoutput.Size = New-Object System.Drawing.Size(155, 200)
$pcoutput.Location = New-Object System.Drawing.Size(156, 5)
$pcoutput.Text = "Idle ...`r`n"
$form.Controls.Add($pcoutput)

$install_Onclick = {
	ForEach ($app in $software)
	{
		$dycheck = "`$Install" + $app.Shortname
        
		if (($form.Controls | ?{$_.name -eq $dycheck.trim('$')}).checked)
		{
			$name = $app.FriendlyName
			$pcoutput.AppendText("Installing `$name ...`r`n")
		}
		else
		{
			Get-Variable $dycheck
			$pcoutput.AppendText("Not Checked $name ...`r`n")
		}
	}
}

# Install Button begins the installation proces based on checkboxes checked.
$installButton = New-Object System.Windows.Forms.Button
$installButton.Name = "installButton"
$installButton.Text = "Install"
$installButton.Location = New-Object System.Drawing.Size(5, 175)
$installButton.add_Click($install_Onclick)
$form.Controls.Add($installButton)

$form.ShowDialog()

Thank you both. Brian B. your solution worked perfectly.

You’re very welcome. There is likely some better way to do the same thing that i’m not aware of. Maybe someone will see this and make a cleaner suggestion. Just glad it worked for you. It was a nice distraction from what I was working on. I was frustrated with my GUI i’m writing so i took a break to figure out this. :slight_smile:

Brian

Here is the final code

$scriptpath = $MyInvocation.MyCommand.Path
$dir = Split-Path $scriptpath

$site = "\\rootpath"

$software = Import-CSV -Path "$dir\Test\software.txt"
$software | Measure-Object | Out-Null

$count = $software.Count

# Start Form Build
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing

# Form Layout Variables
$form = New-Object system.Windows.Forms.Form
$form.Text = "Software Install v2.0" # Form Title
$form.Height = 250
$form.Width = 350

$i = 0
ForEach ($app in $software) {
	$VariableName = "Install" + $app.ShortName
	"Creating $VariableName"
	New-Variable -Name $VariableName -Value (new-object system.windows.forms.checkbox) -Force
	$form.Controls.Add((get-variable $VariableName).Value)
	(get-variable $VariableName).value.Text = $app.FriendlyName
	$i++
	$y = $i * 20
	(get-variable $VariableName).value.Location = New-Object System.Drawing.Size(20, $y)
	(get-variable $VariableName).value.Size = New-Object System.Drawing.Size(145, 20)
}

$pcoutput = New-Object System.Windows.Forms.TextBox
$pcoutput.MultiLine = $True
$pcoutput.ReadOnly = $True
$pcoutput.BackColor = "White"
$pcoutput.ScrollBars = "Vertical"
$pcoutput.Size = New-Object System.Drawing.Size(155, 200)
$pcoutput.Location = New-Object System.Drawing.Size(156, 5)
$pcoutput.Text = "Idle ...`r`n"
$form.Controls.Add($pcoutput)

$install_Onclick = {
	ForEach ($app in $software) {
		$name = $app.FriendlyName
		$path = $app.Path
		$var = $app.Variable
		$pathend = $path.LastIndexOf("`.")
		$typebegin = $pathend + 1
		$type = $path.Substring($typebegin)
		if ((get-variable ("Install" + $app.Shortname)).value.Checked) {
			$pcoutput.AppendText("Installing $name ...`r`n")
			if ($type -eq "bat") {
				Start-Process "$site$path" -Wait
			}
			else {
				cscript "$site$path" $var
			}
		}
		else {
			(get-variable ("Install" + $app.Shortname)).value
			$pcoutput.AppendText("Not Checked $name ...`r`n")
		}
	}
}

# Install Button begins the installation process based on checkboxes checked.
$installButton = New-Object System.Windows.Forms.Button
$installButton.Name = "installButton"
$installButton.Text = "Install"
$installButton.Location = New-Object System.Drawing.Size(5, 175)
$installButton.add_Click($install_Onclick)
$form.Controls.Add($installButton)

$form.ShowDialog()

I will be adding some more controls like which site the user is at and logging. Again thank you very much.