Powershell Add_CheckStateChanged in an array of checkboxes - arrays

In a tab of my form, I show as much checkbox as I have scheduled tasks with specifics labels. Below, I have a button which is disabled, and I want it enabled only if I have at least one of the checkbox checked.
So I add a "Add_CheckStateChanged" but it activate the button only with the last checkbox. When I check among the firsts checkboxes, it does nothing with the button.
Here is the part of script:
function getTasks($path) {
$out = #()
$schedule.GetFolder($path).GetTasks(0) | % {
$xml = [xml]$_.xml
$out += New-Object psobject -Property #{
"Name" = $_.Name
"Path" = $_.Path
"LastRunTime" = $_.LastRunTime
"NextRunTime" = $_.NextRunTime
"Actions" = ($xml.Task.Actions.Exec | % { "$($_.Command) $($_.Arguments)" }) -join "`n"
}
}
$schedule.GetFolder($path).GetFolders(0) | % {
$out += getTasks($_.Path)
}
$out
}
$tasks = #()
$schedule = New-Object -ComObject "Schedule.Service"
$schedule.Connect()
$tasks += getTasks("\")
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($schedule) | Out-Null
Remove-Variable schedule
$tasksMySoft = $tasks | Where-Object {$_.Name -match "MySoft1|MySoft2|MySoft3|MySoft4|MySoft5|MySoft6"}
$CheckBoxLabels = $tasksMySoft.name
$CheckBoxCounter = 1
$CheckBoxes = foreach($taskLabel in $CheckBoxLabels) {
$CheckBox = New-Object System.Windows.Forms.CheckBox
$CheckBox.DataBindings.DefaultDataSourceUpdateMode = 0
$CheckBox.UseVisualStyleBackColor = $True
$System_Drawing_Size = New-Object System.Drawing.Size
$System_Drawing_Size.Width = 175
$System_Drawing_Size.Height = 20
$CheckBox.Size = $System_Drawing_Size
$CheckBox.TabIndex = 2
$CheckBox.Text = $taskLabel
$System_Drawing_Point = New-Object System.Drawing.Point
if($CheckBoxCounter -lt 9){
$System_Drawing_Point.X = 90}
elseif($CheckBoxCounter -ge 9){
$System_Drawing_Point.X = 275}
if($CheckBoxCounter -lt 9){
$System_Drawing_Point.Y = 45 + (($CheckBoxCounter - 1) * 20)}
elseif($CheckBoxCounter -ge 9){
$System_Drawing_Point.Y = - 115 + (($CheckBoxCounter - 1) * 20)}
$CheckBox.Location = $System_Drawing_Point
$CheckBox.Name = "CheckBox$CheckBoxCounter"
$CheckBox.Add_CheckStateChanged({
if($CheckBox.checked -eq $True){
$GenerateButton.Enabled = $true
}else{
$GenerateButton.Enabled = $false}
})
$tab.Controls.Add($CheckBox)
$CheckBox
$CheckBoxCounter++
}
Some help would be nice ;)

I found on my own. I replaced
$CheckBox.Add_CheckStateChanged({
if($CheckBox.checked -eq $True){
$GenerateButton.Enabled = $true
}else{
$GenerateButton.Enabled = $false}
})
by
$CheckBox.Add_CheckStateChanged({
foreach($CheckBox in $CheckBoxes | Where-Object {$_.checked -eq $false}) {
$GenerateButton.Enabled = $false}
})
$CheckBox.Add_CheckStateChanged({
foreach($CheckBox in $CheckBoxes | Where-Object {$_.checked -eq $true}) {
$GenerateButton.Enabled = $true}
})

Related

Powershell Listview : Add 6 items lists in 6 different columns

I have an issue with my PS script including a listview.
I need to check the content of 6 directorys and show the content in 6 different columns :
The issue is that i can't get a correct visual, they are all in the same column
Here is my code :
$Form = New-Object Windows.Forms.Form
$Form.Text = "New Test"
$Form.Width = 1550
$Form.Height = 800
$Listview = New-Object System.Windows.Forms.ListView
$Listview.Location = New-Object System.Drawing.Size(15,10)
$Listview.Size = New-Object System.Drawing.Size(550,10)
$Listview.AutoResizeColumns([System.Windows.Forms.ColumnHeaderAutoResizeStyle]::ColumnContent)
$Listview.View = "Details"
$Listview.FullRowSelect = $true
$Listview.GridLines = $true
$Listview.Height = 650
$Listview.Width =1500
$Listview.AllowColumnReorder = $true
$Listview.Sorting = [System.Windows.Forms.SortOrder]::None
#[void]$Listview.Columns.Add('Null',0)
[void]$Listview.Columns.Add('Scripts',150)
[void]$Listview.Columns.Add('Applications',150)
[void]$Listview.Columns.Add('Systems',500)
[void]$Listview.Columns.Add('Databases',100)
[void]$Listview.Columns.Add('Datas',150)
[void]$Listview.Columns.Add('Backups',500)
$oButton = New-Object Windows.Forms.Button
$oButton.Text = "List"
$oButton.Top = 700
$oButton.Left = 350
$oButton.Width = 150
$oButton.Anchor = [System.Windows.Forms.AnchorStyles]::Bottom -bor [System.Windows.Forms.AnchorStyles]::Right
$a = (Get-ChildItem "C:\Scripts\").Name
$b = (Get-ChildItem "C:\Applications\").Name
$c = (Get-ChildItem "C:\Systems\").Name
$d = (Get-ChildItem "C:\Databases\").Name
$e = (Get-ChildItem "C:\Datas\").Name
$f = (Get-ChildItem "C:\Backups\").Name
$Entry = New-Object System.Windows.Forms.ListViewItem($_.Null)
foreach($mp in $a){
$Entry1 = New-Object System.Windows.Forms.ListViewItem($_.Scripts)
$Listview.Items.Add($mp)
}
foreach($mp1 in $b){
$Entry2 = New-Object System.Windows.Forms.ListViewItem($_.Applications)
$Listview.Items.Add($Entry2).SubItems.Add($mp1)
}
foreach($mp2 in $c){
$Entry3 = New-Object System.Windows.Forms.ListViewItem($_.Systems)
$Listview.Items.Add($Entry3).SubItems.Add($mp2)
}
foreach($mp3 in $d){
$Entry4 = New-Object System.Windows.Forms.ListViewItem($_.Databases)
$Listview.Items.Add($Entry4).SubItems.Add($mp3)
}
foreach($mp4 in $e){
$Entry5 = New-Object System.Windows.Forms.ListViewItem($_.Datas)
$Listview.Items.Add($Entry5).SubItems.Add($mp4)
}
foreach($mp5 in $f){
$Entry6 = New-Object System.Windows.Forms.ListViewItem($_.Backup)
$Listview.Items.Add($Entry6).SubItems.Add($mp5)
}
$Form.Add_Shown({$Form.Activate()})
$Form.controls.add($oButton)
$Form.controls.add($Listview)
$Form.ShowDialog()
I tried a lot of change but im still blocked
Thanks in advance for you help
Regards

Ping Multiple IP/HostNames

I am just trying to make a simple IP/Hostname checker. The one part I am struggling with is getting it to ping each item from a list. It only shows the result of the first, or last one.
I have tried adding items from the text box into an array and pinging them that way, and it had the same results.
Here is my Current Code.
[System.Windows.Forms.Application]::EnableVisualStyles()
function ping-list{
$IPStatus.Text = ""
$names = #($IPList.text)
$Names | ForEach-Object{
if (Test-Connection -ComputerName $_ -Count 1){
$IPStatus.Text += "$_ is Online"
Write-Host "$_ is Online"
}
else{
$IPStatus.Text += "$_ is Offline"
Write-Host "$_ is Offline"
}
}
}
$Pinger = New-Object system.Windows.Forms.Form
$Pinger.ClientSize = '657,557'
$Pinger.text = "Pinger"
$Pinger.TopMost = $false
$IPStatus = New-Object system.Windows.Forms.TextBox
$IPStatus.multiline = $true
$IPStatus.width = 234
$IPStatus.height = 498
$IPStatus.enabled = $true
$IPStatus.location = New-Object System.Drawing.Point(408,45)
$IPStatus.Font = 'Microsoft Sans Serif,10'
$IPStatus.Text = "Ready"
$IPList = New-Object system.Windows.Forms.TextBox
$IPList.multiline = $true
$IPList.width = 234
$IPList.height = 498
$IPList.enabled = $true
$IPList.location = New-Object System.Drawing.Point(15,45)
$IPList.Font = 'Microsoft Sans Serif,10'
$IPList.Text = #("127.0.0.1")
$PingButton = New-Object system.Windows.Forms.Button
$PingButton.text = "button"
$PingButton.width = 60
$PingButton.height = 30
$PingButton.location = New-Object System.Drawing.Point(298,240)
$PingButton.Font = 'Microsoft Sans Serif,10'
$PingButton.Add_Click({ping-list})
$Pinger.controls.AddRange(#($IPStatus,$IPList,$PingButton))
$Pinger.Add_Shown( {$Pinger.Activate()})
$Pinger.ShowDialog()
$IPList.text gets all the text in the textbox.
Instead use Lines
function ping-list{
$IPStatus.Text = ""
$Names = #($IPList.Lines)
$Names | ForEach-Object{
if (Test-Connection -ComputerName $_ -Count 1){
$IPStatus.Text += "$_ is Online`r`n"
Write-Host "$_ is Online"
}
else{
$IPStatus.Text += "$_ is Offline`r`n"
Write-Host "$_ is Offline"
}
}
}

How to close form GUI after checking existing file in PowerShell?

I want to check an existing file, if the process still waiting for the file, it will display a GUI window. After the file is exist, the window will close automatically.
I tried this code, the window can not close, even the file already exist.
Checking the file:
$SN = "708TSTA"
$MAC = "2E5961370"
function Find {
$n = 0
while (-not (Get-ChildItem -Name "D:\SERVER\" | Where-Object {$_ -like "*$SN-$MAC*"})) {
Start-Sleep -s 1
D:\Auto\GUI.ps1
$n++
(Get-ChildItem -Name "D:\SERVER\" | Where-Object {$_ -like "*$SN-$MAC*"})
Write-Host "Attempt no $n"
}
Write-Host ">>Flag found after $n attempts"
return $true
}
if (Find) {
Write-Host "Found"
}
GUI.ps1:
Add-Type -AssemblyName System.Windows.Forms
[System.Windows.Forms.Application]::EnableVisualStyles()
$Form = New-Object System.Windows.Forms.Form
$Form.ClientSize = '578,400'
$Form.Text = "Form"
$Form.BackColor = "#c1daf7"
$Form.WindowState = 'Maximized'
$Form.FormBorderStyle = "FixedDialog"
$Label1 = New-Object System.Windows.Forms.Label
$Label1.Text = "UNDER PROCESS"
$Label1.AutoSize = $true
$Label1.Width = 25
$Label1.Height = 10
$Label1.Location = New-Object System.Drawing.Point(600,300)
$Label1.Font = 'Microsoft Sans Serif,30,style=Bold,Underline'
$Label1.ForeColor = "#d0021b"
$Label2 = New-Object System.Windows.Forms.Label
$Label2.Text = "WAITING"
$Label2.AutoSize = $true
$Label2.Width = 25
$Label2.Height = 10
$Label2.Location = New-Object System.Drawing.Point(770,500)
$Label2.Font = 'Microsoft Sans Serif,20,style=Bold'
$Label2.ForeColor = "#fb0505"
$Check = Get-ChildItem -Name "D:\SERVER\" | Where-Object {$_ -like "*$SN-$MAC*"}
if($Check) {
Write-Host "File Exist"
$Form.Close()
}
$Form.Controls.AddRange(#($Label1,$Label2))
[void]$Form.ShowDialog()
Instead of doing Start-Sleep inside the GUI, it is better to use a timer so the form stays responsive.
I changed the code of the GUI.ps1 (not the way it looks) like this:
Param (
[string]$Path = '*.*',
[string]$MaxAttempts = 5
)
Add-Type -AssemblyName System.Windows.Forms
[System.Windows.Forms.Application]::EnableVisualStyles()
# set things up for the timer
$script:nAttempts = 0
$timer = New-Object System.Windows.Forms.Timer
$timer.Interval = 1000 # 1 second
$timer.Add_Tick({
$global:Result = $null
$script:nAttempts++
$file = Get-Item -Path $Path
if ($file) {
$global:Result = [PSCustomObject]#{
Exists = $true
FileName = $file.FullName
Attempts = $script:nAttempts
}
$timer.Dispose()
$Form.Close()
}
elseif ($script:nAttempts -ge $MaxAttempts) {
$global:Result = [PSCustomObject]#{
Exists = $false
FileName = ''
Attempts = $script:nAttempts
}
$timer.Dispose()
$Form.Close()
}
})
$Form = New-Object System.Windows.Forms.Form
$Form.ClientSize = '578,400'
$Form.Text = "Form"
$Form.BackColor = "#c1daf7"
$Form.WindowState = 'Maximized'
$Form.FormBorderStyle = "FixedDialog"
$Label1 = New-Object System.Windows.Forms.Label
$Label1.Text = "UNDER PROCESS"
$Label1.AutoSize = $true
$Label1.Width = 25
$Label1.Height = 10
$Label1.Location = New-Object System.Drawing.Point(600,300)
$Label1.Font = 'Microsoft Sans Serif,30,style=Bold,Underline'
$Label1.ForeColor = "#d0021b"
$Label2 = New-Object System.Windows.Forms.Label
$Label2.Text = "WAITING"
$Label2.AutoSize = $true
$Label2.Width = 25
$Label2.Height = 10
$Label2.Location = New-Object System.Drawing.Point(770,500)
$Label2.Font = 'Microsoft Sans Serif,20,style=Bold'
$Label2.ForeColor = "#fb0505"
$Form.Controls.AddRange(#($Label1,$Label2))
# start the timer as soon as the dialog is visible
$Form.Add_Shown({ $timer.Start() })
[void]$Form.ShowDialog()
# clean up when done
$Form.Dispose()
And to call it from your other script, use:
$SN = "708TSTA"
$MAC = "2E5961370"
function Test-FileExists {
$file = Get-Item -Path "D:\*$SN-$MAC*"
if ($file) {
$global:Result = [PSCustomObject]#{
Exists = $true
FileName = $file.FullName
Attempts = 1
}
}
else {
& "D:\GUI.ps1" -Path "D:\*$SN-$MAC*" -MaxAttempts 3
}
}
# call the function that can call the GUI.ps1 script
Test-FileExists
# check the Global result object
if ($global:Result.Exists) {
Write-Host "File '$($global:Result.FileName)' Exists. Found after $($global:Result.Attempts) attempts." -ForegroundColor Green
}
else {
Write-Host "File not found after $($global:Result.Attempts) attempts." -ForegroundColor Red
}
Update
As per your comments, I understand that the calling script should show the form (which does nothing more that show on screen) AND is responsible for closing it after the file has been found.
The code below should do what you ask by defining the $Form as a global variable and by using the .Show() method of the form instead of ShowDialog():
GUI.ps1
Add-Type -AssemblyName System.Windows.Forms
[System.Windows.Forms.Application]::EnableVisualStyles()
$global:Form = New-Object System.Windows.Forms.Form
$global:Form.ClientSize = '578,400'
$global:Form.Text = "Form"
$global:Form.BackColor = "#c1daf7"
$global:Form.WindowState = 'Maximized'
$global:Form.FormBorderStyle = "FixedDialog"
$global:Form.ControlBox = $false # hide sizing and close buttons
$global:Form.TopMost = $true
$Label1 = New-Object System.Windows.Forms.Label
$Label1.Text = "UNDER PROCESS"
$Label1.AutoSize = $true
$Label1.Width = 25
$Label1.Height = 10
$Label1.Location = New-Object System.Drawing.Point(600,300)
$Label1.Font = 'Microsoft Sans Serif,30,style=Bold,Underline'
$Label1.ForeColor = "#d0021b"
$Label2 = New-Object System.Windows.Forms.Label
$Label2.Text = "WAITING"
$Label2.AutoSize = $true
$Label2.Width = 25
$Label2.Height = 10
$Label2.Location = New-Object System.Drawing.Point(770,500)
$Label2.Font = 'Microsoft Sans Serif,20,style=Bold'
$Label2.ForeColor = "#fb0505"
$global:Form.Controls.AddRange(#($Label1,$Label2))
# don't use ShowDialog() here because it will block the calling script
$global:Form.Show()
the calling script
function Test-FileExists {
[CmdletBinding()]
param (
[parameter(Mandatory = $true, ValueFromPipeline = $true, Position = 0)]
[string]$Path,
[string]$Pattern = '*.*'
)
$nAttempts = 1
$file = Get-ChildItem -Path $Path -Filter $Pattern -File | Select-Object -First 1
if (!$file) {
# show the GUI
& "D:\GUI.ps1"
do {
Start-Sleep -Seconds 1
$nAttempts++
Write-Verbose "Attempt No. $nAttempts"
$file = Get-ChildItem -Path $Path -Filter $Pattern -File | Select-Object -First 1
} until ($file)
# clean up the form
$global:Form.Dispose()
$global:Form = $null
}
Write-Verbose "File '$($file.FullName)' Exists. Found after $nAttempts attempt(s)."
return $true
}
$SN = "708TSTA"
$MAC = "2E5961370"
# call the function that can call the GUI.ps1 script
if (Test-FileExists -Path 'D:\SERVER\SHARE' -Pattern "*$SN-$MAC*" -Verbose) {
Write-Host "Found"
}
Hope that helps

Manual Checkbox enable

I have a ComboBox control on my form. What I want is when I change an item in the ComboBox from one to another, the event was handled. It is important that when changing and not when choosing the same element. All this time I used ComboBox.Add_SelectionChangeCommitted($function), but soon I realized that the block that is also executed by the handler when the same (selected) item is selected from the list. A little digging in ComboBox events I am completely confused. Having tried several events (SelectedItemChanged, SelectedIndexChanged) I could never able to achieve the desired result.
An example of what I want to do and what should not be done several times when choosing the same element. When the block of code for Manual is executed several times, the contents of all TextBox are cleared, but I don’t want to.
Add-Type -AssemblyName System.Windows.Forms
[System.Windows.Forms.Application]::EnableVisualStyles()
$Form = New-Object system.Windows.Forms.Form
$Form.ClientSize = '420,240'
$Form.TopMost = $false
$Form.FormBorderStyle = 'Fixed3D'
$Form.MaximizeBox = $false
$ComboBox = New-Object system.Windows.Forms.ComboBox
$ComboBox.width = 391
$ComboBox.height = 47
#('Automatic (DHCP)','Manual Input') | ForEach-Object {[void] $ComboBox.Items.Add($_)}
$ComboBox.location = New-Object System.Drawing.Point(13,57)
$ComboBox.DropDownStyle = 'DropDownList'
$ComboBox.DrawMode = 'OwnerDrawFixed'
$Button = New-Object system.Windows.Forms.Button
$Button.text = "Set"
$Button.width = 60
$Button.height = 30
$Button.visible = $false
$Button.enabled = $false
$Button.location = New-Object System.Drawing.Point(336,126)
$CheckBox = New-Object system.Windows.Forms.CheckBox
$CheckBox.width = 65
$CheckBox.height = 15
$CheckBox.visible = $false
$CheckBox.Checked = $false
$CheckBox.enabled = $true
$CheckBox.location = New-Object System.Drawing.Point(16,210)
$TextBox1 = New-Object system.Windows.Forms.TextBox
$TextBox1.Name = "TextBox1"
$TextBox1.multiline = $false
$TextBox1.width = 40
$TextBox1.height = 20
$TextBox1.visible = $false
$TextBox1.enabled = $true
$TextBox1.location = New-Object System.Drawing.Point(81,100)
$TextBox2 = New-Object system.Windows.Forms.TextBox
$TextBox2.Name = "TextBox2"
$TextBox2.multiline = $false
$TextBox2.width = 40
$TextBox2.height = 20
$TextBox2.visible = $false
$TextBox2.enabled = $false
$TextBox2.location = New-Object System.Drawing.Point(81,208)
$Form.controls.AddRange(#($TextBox1,$TextBox2,$Button,$ComboBox,$CheckBox))
$global:ManualChecked = $null
$global:AutomaticChecked = $null
$ComboBox.Add_SelectionChangeCommitted($methodSelection)
$netwValues = New-Object 'System.Collections.Hashtable'
$methodSelection =
{
switch($ComboBox.Text)
{
"Manual Input"
{
$CheckBox.Visible = $Button.Visible = $true
$Button.Enabled = $false
ForEach ($control in $Form.controls)
{
if ($control -is [System.Windows.Forms.TextBox] )
{
$control.Visible = $control.Enabled = $true
$control.Clear()
if($netwValues.Count -gt 0)
{
$control.Text = $netwValues.Item($control.Name)
$netwValues.Remove($control.Name)
}
}
}
if($global:ManualChecked -eq 1)
{
$CheckBox.Checked = $true
$TextBox2.Enabled = $true
}
else
{
$CheckBox.Checked = $false
$TextBox2.Enabled = $false
}
}
"Automatic (DHCP)"
{
ForEach($control in $Form.controls)
{
if($control -is [System.Windows.Forms.TextBox] -or $control -is [System.Windows.Forms.CheckBox] -or $control -is [System.Windows.Forms.Button])
{
$control.Visible = $control.Enabled = $true
if($control -is [System.Windows.Forms.Label] -or $control -is [System.Windows.Forms.TextBox])
{
$control.Enabled = $false
if($control -is [System.Windows.Forms.TextBox])
{
if($control.Text.Length)
{
$netwValues.Add($control.Name,$control.Text)
$control.Clear()
}
}
}
}
}
if($global:AutomaticChecked -eq 1)
{
$CheckBox.Checked = $true
}
else
{
$CheckBox.Checked = $false
}
}
}
}
You can implement this logic yourself.
# Simple class for using as item for combobox instead of just string.
class CbItem
{
CbItem([string] $value)
{
$this.Value = $value
}
[string] $Value
[string] ToString()
{
return $this.Value
}
}
# Add instances of this class into combobox.
$ComboBox.Items.Add([CbItem]::new('Automatic (DHCP)'))
$ComboBox.Items.Add([CbItem]::new('Manual Input'))
# Create a variable for storing current combobox's item.
$global:CurrentCbItem = $null
# Add logic at the begining of handler for exiting if selected item is the same as the last one.
$methodSelection =
{
if ([Object]::ReferenceEquals($global:CurrentCbItem, $ComboBox.SelectedItem))
{
return
}
$global:CurrentCbItem = $ComboBox.SelectedItem
...
}

How Do I Access CheckBoxes From a Function

I've created a form and dynamically added CheckBoxes and CheckBox names. How can I programmatically check one particular CheckBox from the Get-LicenseDetails function? Missing bracket has been added.
import-module MSOnline
Function Get-LicenseDetails {
Param ($upn)
$licenses = Get-MsolUser -UserPrincipalName $upn
ForEach ($license in $licenses.Licenses) {
If ($license.AccountSkuId -like '*ENTERPRISEPACK') {
$serviceName = $serviceStatus.ServicePlan.ServiceName
$checkBox.Checked = $true
}
}
}
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
$System_Drawing_Point = New-Object System.Drawing.Point
Add-Type -AssemblyName System.Windows.Forms
$form = New-Object Windows.Forms.Form
$form.Text = "Office 365 Licensing"
$form.Name = "Form1"
$form.Size = New-Object Drawing.Size #(316, 510)
#SEARCH BUTTON
$searchBtn = New-Object System.Windows.Forms.Button
$System_Drawing_Point.X = 226
$System_Drawing_Point.Y = 38
$searchBtn.Location = $System_Drawing_Point
$searchBtn.add_click({Get-LicenseDetails "user.name#domain.com"})
$searchBtn.Size = New-Object System.Drawing.Size(67, 23)
$searchBtn.Text = "Click Me"
$form.Controls.Add($searchBtn)
#CHECKBOXES
$y = 80
$Services = (Get-MsolAccountSku | Where-Object {$_.SkuPartNumber -eq "ENTERPRISEPACK"}).ServiceStatus.ServicePlan.ServiceName
ForEach ($service in $Services) {
$checkbox = New-Object System.Windows.Forms.CheckBox
$checkbox.Text = $service
$checkbox.Name = "CheckBox_$service"
$checkbox.Size = New-Object System.Drawing.Size(260,17)
$checkbox.Location = New-Object System.Drawing.Size(10,$y)
$y += 25
$form.Controls.Add($checkbox)
}
$drc = $form.ShowDialog()
First of all, you are missing a square Bracket where you load the System.Drawing Assembly.
You could access the CheckBox in the Get-LicenseDetails bei either passing them to the function or by accessing them using $global:. However, I wouldn't pass GUI elements to that function. Instead I would create a model (new object) and pass that to the Get-LicenseDetails method.
OK, I've figured it out. I used these lines in the function:
$checkBoxName = "CheckBox_" + $serviceName
$checkbox = $form.Controls | Where-Object {$_.name -eq $checkBoxName}
$checkbox.Checked = $true

Resources