PowerShell Winforms MoveUp/MoveDown - winforms

Have only recently started getting into PowerShell forms and it's proving to be a minefield on support once I hit a wall. There's so much out there for c# but more often than not I struggle to convert it to PowerShell.
The code below is a snippet of a much larger script for Skype stuff (excuse the poor late out, no point adding irreverent code). What I'm struggling to do is create Move Up/Move Down buttons for when my CheckedListBox is populated.
The CheckedListBox is important since everyone within the list will be added to a Skype response group, and everyone checked will be designated an admin of the group. The Move Up/Move Down buttons will be used for priority purposes when this type of routing is selected.
#Function for creating an "open file" button
Function OpenFileDialog
{ [System.Reflection.Assembly]::LoadWithPartialName( "System.Windows.Forms" ) | Out-Null
$OBJFORM = New-Object System.Windows.Forms.OpenFileDialog
$OBJFORM.Filter = "Text files (*.txt)|*.txt"
$TXTIMPORT = $OBJFORM.ShowDialog()
IF ( $TXTIMPORT -eq "OK" )
{ Return $OBJFORM.FileName } }
# ///////////////
#Function for importing users
Function ImportUsers
{ $USERS = gc $TAB2IMPORT
$SIPUSERS = #()
foreach ( $USER in $USERS )
{ $USERSIP = ( "sip:" + $_ )
$SIPUSERS += $USERSIP
IF ( $USERSIP -ne $NULL )
{ [void]$TAB2LISTBOX.Items.Add( $USERSIP ) }
IF ( $SIPUSERS.Count -ge 2 )
{ $TAB2LISTL.Visible = $TRUE } } }
# ///////////////
# Adds .NET assemby's and turns on visual themes in standard PowerShell.
Add-Type -AssemblyName System.Drawing
Add-Type -AssemblyName System.Windows.Forms
[System.Windows.Forms.Application]::EnableVisualStyles()
# ///////////////
# Creates the parent form and controls
$SDC = New-Object System.Windows.Forms.Form
$SDC.Location = '270,175'
$SDC.Size = '900,600'
$SDC.StartPosition = "CenterScreen"
$SDC.BackColor = "Lavender"
$SDC.Font = "Calibri, 8.5"
$SDC.FormBorderStyle = "Fixed3D"
$TABC = New-Object System.Windows.Forms.TabControl
$TABC.Location = '140,20'
$TABC.Size = '720,520'
$TABC.SizeMode = "Fixed"
$SDC.Controls.Add( $TABC )
# ///////////////
#Tab controls
$TAB2 = New-Object System.Windows.Forms.TabPage
$TAB2.Location = '20,40'
$TAB2.Size = '100,100'
$TAB2.Text = "Response Group"
$TAB2.Padding = New-Object System.Windows.Forms.Padding ( 3,3,3,3 )
$TAB2.AutoScroll = $TRUE
$TABC.Controls.Add( $TAB2 )
# ///////////////
#Tab 2 ( Migrate users to Skype )
$TAB2HEADER = New-Object System.Windows.Forms.Label
$TAB2HEADER.Font = New-Object System.Drawing.Font( "Calibri",11,[System.Drawing.FontStyle]::Bold )
$TAB2HEADER.Location = '50,30'
$TAB2HEADER.Size = '620,30'
$TAB2HEADER.Text = "This tab will create a response group."
$TAB2.Controls.Add( $TAB2HEADER )
# ///////////////
#Tab 2 Add Users to Hunt Group
$TABAGENTSL = New-Object System.Windows.Forms.Label
$TABAGENTSL.Font = New-Object System.Drawing.Font( "Calibri",8,[System.Drawing.FontStyle]::Bold )
$TABAGENTSL.Location = '50,420'
$TABAGENTSL.Size = '200,20'
$TABAGENTSL.Text = "Who do you want adding to the group?"
$TAB2.Controls.Add( $TABAGENTSL )
#Tab 2 Open File Button
$TAB2IMPORT = New-Object System.Windows.Forms.Button
$TAB2IMPORT.Location = '50,450'
$TAB2IMPORT.Size = '80,20'
$TAB2IMPORT.Text = "File Import"
$TAB2.Controls.Add( $TAB2IMPORT )
$TAB2IMPORT.Add_Click( { $TAB2IMPORT = OpenFileDialog ; ImportUsers } )
# ///////////////
#Tab 2 ListBox for Users
$TAB2LISTBOX = New-Object System.Windows.Forms.CheckedListBox
$TAB2LISTBOX.Location = '320,120'
$TAB2LISTBOX.Size = '200,200'
$TAB2.Controls.Add( $TAB2LISTBOX )
#Tab 2 Listbox Help
$TAB2LISTL = New-Object System.Windows.Forms.Label
$TAB2LISTL.Font = New-Object System.Drawing.Font( "Calibri",8,[System.Drawing.FontStyle]::Italic )
$TAB2LISTL.Location = '550,120'
$TAB2LISTL.Size = '150,80'
$TAB2LISTL.Text = "All names within the list will be added to the response group. `nThose checked will be designated response group admins"
$TAB2LISTL.Visible = $FALSE
$TAB2.Controls.Add( $TAB2LISTL )
$TAB2LISTMU = New-Object System.Windows.Forms.Button
$TAB2LISTMU.Location = '530,260'
$TAB2LISTMU.Text = "&Move Up"
$TAB2.Controls.Add( $TAB2LISTMU )
$SDC.Add_Shown( { $SDC.Activate() } )
$SDC.ShowDialog()
I bought PowerShell Pro Tools for Visual Studio but hit the same stumbling blocks in that if I don't know what tool it is I need to begin with, I can't figure out from the options available on screen. As a result I've resided myself to ISE until I die!
Any help would be greatly appreciated. Thanks

I found a link on how to do it.
https://www.akaplan.com/blog/2016/05/move-selected-item-up-or-down-in-powershell-listbox/
*edit
I 'cleaned' up the code for my own use as shown below:
#Function for Move Down
Function MoveDown {
IF ( ( $TAB2LISTBOX.SelectedIndex -ne -1 ) -and ( $TAB2LISTBOX.SelectedIndex -lt $TAB2LISTBOX.Items.Count - 1 ) )
{ $TAB2LISTBOX.BeginUpdate()
$SELECTITEM = $TAB2LISTBOX.SelectedIndex
$TAB2LISTBOX.Items.Insert( $SELECTITEM, $TAB2LISTBOX.Items.Item( $SELECTITEM +1 ) )
$TAB2LISTBOX.Items.RemoveAt( $SELECTITEM +2 )
$TAB2LISTBOX.SelectedIndex = ( $SELECTITEM +1 )
$TAB2LISTBOX.EndUpdate() } }
#Function for Move Up
Function MoveUp {
IF ( $TAB2LISTBOX.SelectedIndex -gt 0 )
{ $TAB2LISTBOX.BeginUpdate()
$SELECTITEM = $TAB2LISTBOX.selectedIndex
$TAB2LISTBOX.Items.Insert( $SELECTITEM -1, $TAB2LISTBOX.Items.Item( $SELECTITEM ) )
$TAB2LISTBOX.SelectedIndex = ( $SELECTITEM -1 )
$TAB2LISTBOX.Items.RemoveAt( $SELECTITEM +1 )
$TAB2LISTBOX.EndUpdate() } }

Related

PowerShell Winforms Textbox updates on other input but overwriteable

Afternoon all,
I wanna believe this one is pretty easy but hitting a wall and can't figure out why.
I have a PowerShell winform that's going to create a new user account from a template. One of the fields I'm working on now is the line manager; once a template account has been found, auto-fill the line manager field, but allow it to be overwritten if this is incorrect.
For the pre-populated stuff I've been using:
$FORMCONTROL.Add_TextChanged( {
However once the template has been found and the line manager field written too, I can't overwrite it. Is there another Event I should be using to populate the box but allow me to delete the content and add something else?
The code below is a much cut down version of what I'm using. The functions allow for finding a user account and populating the ReadOnly box.
Function FindUser {
IF ( $SEARCHUSER -like $NULL -or $SEARCHUSER -like " *" )
{ }
ELSEIF ( $ACCOUNT = dsquery user -samid $SEARCHUSER )
{ $ACCOUNT = Get-ADUser $SEARCHUSER -Property * }
ELSEIF ( $ACCOUNT = Get-ADUser -Filter { mail -eq $SEARCHUSER } -ea sil )
{ $ACCOUNT = Get-ADUser -Filter { mail -eq $SEARCHUSER } -Property * }
ELSEIF ( dsquery user -name $SEARCHUSER )
{ $ACCOUNT = Get-ADUser -Filter { name -eq $SEARCHUSER } -Property * }
ELSE
{ $( foreach ( $SEARCHUSER in ( Get-ADUser -Filter { ( Surname -like $SEARCHUSER ) -and ( Enabled -eq $TRUE )
} -Properties Mail, Department, Office | sort Name ) )
{ $SEARCHUSER | Select Name, #{ N = "Username" ; E = { $_.SamAccountName } }, Mail, Department, Office
} ) | Out-GridView -Title 'Select the user account' -OutputMode Single | %{
TRY
{ $ACCOUNT = Get-ADUser $_.UserName -Property * }
CATCH
{ } } }
IF ( ( $ACCOUNT.SamAccountName ).count -eq 1 )
{ $Script:ACCOUNT = $ACCOUNT }
ELSE
{ $Script:ACCOUNT = $NULL } }
Function TemplateUser {
IF ( $ACCOUNT -ne $NULL )
{ $TAB1TEMPLATE_5.Text = ( $ACCOUNT.Name ) }
ELSEIF ( $TAB1TEMPLATE_3.Text.Length -lt 4 )
{ $TAB1TEMPLATE_5.Text = $NULL } }
# Creates the parent form and controls
$SDC = New-Object System.Windows.Forms.Form
$SDC.Location = New-Object System.Drawing.Size( 270,175 )
$SDC.Size = New-Object System.Drawing.Size( 900,600 )
$SDC.StartPosition = "CenterScreen"
$SDC.BackColor = "Lavender"
$SDC.Font = "Calibri, 8.5"
$SDC.FormBorderStyle = "Fixed3D"
#Tab 1 Template Account Label
$TAB1TEMPLATE_2 = New-Object System.Windows.Forms.Label
$TAB1TEMPLATE_2.Location = '35,90'
$TAB1TEMPLATE_2.Size = '200,20'
$TAB1TEMPLATE_2.Font = New-Object System.Drawing.Font( "Calibri",10,[System.Drawing.FontStyle]::Bold )
$TAB1TEMPLATE_2.Text = "Who are we using as a template?"
$SDC.Controls.Add( $TAB1TEMPLATE_2 )
#Tab 1 Template Textbox
$TAB1TEMPLATE_3 = New-Object System.Windows.Forms.TextBox
$TAB1TEMPLATE_3.Location = '20,115'
$TAB1TEMPLATE_3.Size = '200,20'
$TAB1TEMPLATE_3.Font = New-Object System.Drawing.Font( "Calibri",9 )
$SDC.Controls.Add( $TAB1TEMPLATE_3 )
#Tab 1 Template Textbox - When hit Return
$TAB1TEMPLATE_3.Add_KeyDown( {
IF ( $_.KeyCode -eq 'Enter' )
{ $SEARCHUSER = $TAB1TEMPLATE_3.Text ; FindUser ; TemplateUser } } )
#Tab 1 Template Account's Full Name
$TAB1TEMPLATE_5 = New-Object System.Windows.Forms.TextBox
$TAB1TEMPLATE_5.Location = '20,150'
$TAB1TEMPLATE_5.Size = '200,20'
$TAB1TEMPLATE_5.ReadOnly = $TRUE
$TAB1TEMPLATE_5.Font = New-Object System.Drawing.Font( "Calibri",9 )
$SDC.Controls.Add( $TAB1TEMPLATE_5 )
#Tab 1 Line Manager Label
$TAB1MANAGER_2 = New-Object System.Windows.Forms.Label
$TAB1MANAGER_2.Location = '35,400'
$TAB1MANAGER_2.Name = "Manager"
$TAB1MANAGER_2.Size = '245,20'
$TAB1MANAGER_2.Font = New-Object System.Drawing.Font( "Calibri",10,[System.Drawing.FontStyle]::Bold )
$TAB1MANAGER_2.Text = "Line Manager"
$SDC.Controls.Add( $TAB1MANAGER_2 )
#Tab 1 Line Manager Textbox
$TAB1MANAGER_3 = New-Object System.Windows.Forms.TextBox
$TAB1MANAGER_3.Location = '20,420'
$TAB1MANAGER_3.Size = '245,20'
$TAB1MANAGER_3.Name = "Manager"
$TAB1MANAGER_3.Font = New-Object System.Drawing.Font( "Calibri",9 )
$SDC.Controls.Add( $TAB1MANAGER_3 )
$TAB1MANAGER_3.Text = $( If ( $TAB1TEMPLATE_3.text -eq $NULL ) { "hi" } )
$SDC.ShowDialog()
I appear to have fixed it by editing the Function TemplateUser:
Function TemplateUser {
IF ( $ACCOUNT -ne $NULL )
{ $TAB1TEMPLATE_5.Text = ( $ACCOUNT.Name )
$TAB1MANAGER_3.Text = ( Get-ADUser $ACCOUNT.Manager ).Name
}
ELSEIF ( $TAB1TEMPLATE_3.Text.Length -lt 4 )
{ $TAB1TEMPLATE_5.Text = $NULL } }
Lord knows what I was doing wrong in the first place as didn't save the changes.
#TheIncorrigible1 - Curious to know what you mean by the formatting. Genuinely. Is there a more efficient way of writing? I'm aware that when complete this script is going to be pretty big so if I'm using unnecessary code I'm all ears.

powershell combobox items to variable

I am trying to create a powershell Script with a Gui that gives the user a drop list of available drives and then when the user selects the drive and clicks ok the script maps that drive as M:\
But I cant work out how to get the selected item in the combo box to be passed into the variable $MapDrive
#List of Drives To Map
$DriveList = #("0. DGL_Data","1. P1","2. DGLFSG3","3. p3 (TPC)","4. p4","6. p6","7. p7","8. p8","9. p9","10. p10","11. p11","12. p12")
#Displays With Drive to Map
$MapDrive = convert.ToString($Dropdown.SelectedItem)
Function MapDrive {
If ($MapDrive -eq $DriveList[0]){
Write-Output Sucess > "C:\Users\andy.burton\Desktop\Practice Selector\Success.txt"}
ElseIf ($MapDrive -eq $DriveList[1]){
Write-Output BooYah > "C:\Users\andy.burton\Desktop\Practice Selector\Yes.txt"
}
Else {
Write-Output Failure > "C:\Users\andy.burton\Desktop\Practice Selector\Failed.txt"}
}
#test Function
Function test {
Write-Output $MapDrive > "C:\Users\andy.burton\Desktop\Practice Selector\Success.txt"
}
#Function to Create Form
Function GenerateForm {
#Define Drive Selector Main Form
Add-Type -AssemblyName System.Windows.Forms
$DGL = New-Object system.Windows.Forms.Form
$DGL.Text = "DGL Practice Manager"
$DGL.TopMost = $true
$DGL.BackgroundImage = [system.drawing.image]::FromFile("C:\Users\andy.burton\Desktop\Practice Selector\Images\medical.jpg")
$DGL.Icon = New-Object system.drawing.icon("C:\Users\andy.burton\Desktop\Practice Selector\Images\medical2.ico")
$DGL.Width = 600
$DGL.Height = 265
$DGL.MinimizeBox = $False
$DGL.MaximizeBox = $False
#Label to Display Instuctions
$label2 = New-Object system.windows.Forms.Label
$label2.Text = "Select which drive"
$label2.BackColor = "#e4f3fa"
$label2.AutoSize = $true
$label2.Width = 25
$label2.Height = 10
$label2.location = new-object system.drawing.point(20,28)
$label2.Font = "Microsoft Sans Serif,10"
$DGL.controls.Add($label2)
#Dropdown Box For Selecting Practice
$Dropdown = New-Object system.windows.Forms.ComboBox
$Dropdown.BackColor = "#e4f3fa"
$DropDown.DropDownStyle = [System.Windows.Forms.ComboBoxStyle]::DropDownList
$Dropdown.Width = 243
$Dropdown.Height = 20
$Dropdown.location = new-object system.drawing.point(21,73)
$Dropdown.Font = "Microsoft Sans Serif,10"
$DropDown.items.addrange($DriveList)
$DGL.controls.Add($Dropdown)
#Cancel Button to Cancel drive Selection
$Cancelbutton = New-Object system.windows.Forms.Button
$Cancelbutton.Text = "Cancel"
$Cancelbutton.Width = 60
$Cancelbutton.Height = 30
$Cancelbutton.location = new-object system.drawing.point(210,120)
$Cancelbutton.Font = "Microsoft Sans Serif,10"
$DGL.CancelButton = $Cancelbutton
$CancelButton.Add_Click({ $DGL.close();[System.Windows.Forms.Application]::Exit($null)})
$DGL.controls.Add($Cancelbutton)
#OK Button to Select Drive
$OKbutton = New-Object system.windows.Forms.Button
$OKbutton.Text = "OK"
$OKbutton.Width = 60
$OKbutton.Height = 30
$OKbutton.location = new-object system.drawing.point(140,120)
$OKbutton.Font = "Microsoft Sans Serif,10"
$DGL.AcceptButton = $OKbutton
$MapDrive = convert.ToString($Dropdown.SelectedItem)
#On click call PracticeSelectedCallBack to launch the application
$OKbutton.Add_Click({test ; $DGL.close()})
$DGL.controls.Add($OKbutton)
#Display the Form
$DGL.Add_Shown({$DGL.Activate()})
$DGL.ShowDialog()
}
GenerateForm
I also want to hide the powershell window but not the gui I have tried -window hidden but that hid everything
The ComboBox has several events that you can tie into that will do various things. One of the events is a SelectedIndexChanged. You can add that event to your ComboBox object and update $MapDrive
This code $MapDrive = convert.ToString($Dropdown.SelectedItem) will only fire once during the initial compile. You have to use events to trigger code changes after compile during runtime.
Also, in Powershell you can use the following command [System.Windows.Forms.ComboBox] | gm to get a list of the methods, and properties of the object. You can use [System.Windows.Forms.checkedlistbox].GetEvents() to get a list of events of an object.

How do I add Checked Items from a CheckedListBox to a Combobox (dropdown) and remove them from the Combobox when unchecked?

I should start by saying that i'm new to PowerShell and i'm still in the learning phase. I've hit a road block and any help would be appreciated.
I have the following code:
# LOAD WINFORMS ASSEMBLY
[reflection.assembly]::LoadWithPartialName( "System.Windows.Forms")
[reflection.assembly]::LoadWithPartialName( "System.Drawing")
# CREATE FORMS
$Form = New-Object Windows.Forms.Form
$Form.text = "Post-Image Configuration Tool"
$Form.Width = 900
$Form.Height = 560
$Form.BackColor = "#3a73b8"
$Form.ForeColor = "White"
$Form.FormBorderStyle = "None"
$Form.StartPosition = "CenterScreen"
# START NETWORK CONFIGURATION PAGE
$GetConnectedAdapters = Get-WmiObject -Class Win32_NetworkAdapter -Filter "NetConnectionStatus = 2" | Select-Object NetConnectionID, Name, MACAddress
$netConfigList1 = New-Object System.Windows.Forms.CheckedListBox
$netConfigList1.Location = New-Object System.Drawing.Size(310,300)
$netConfigList1.Size = New-Object System.Drawing.Size(480,180)
$netConfigList1.Height = 100
$netConfigList1.BackColor = "#3a73b8"
$netConfigList1.ForeColor = "White"
$netConfigList1.BorderStyle = "None"
$netConfigList1.Font = $ListFont
$netConfigList1.add_SelectedIndexChanged({ListNetAdapters})
$netConfigListAdapters = #()
ForEach ($i in $GetConnectedAdapters.NetConnectionID){
$GetAdapterName = Get-WmiObject -Class Win32_NetworkAdapter |Where {$_.NetConnectionID -eq $i} | Select-Object Name, NetConnectionID, MACAddress
$AdapterName = $i +" - " + "("+ $GetAdapterName.Name +")"
$netConfigListAdapters += ,$AdapterName
}
$netConfigList1.Items.AddRange($netConfigListAdapters)
$netConfigSubtext5 = New-Object Windows.Forms.Label
$netConfigSubtext5.Location = New-Object Drawing.Point 290,400
$netConfigSubtext5.Size = New-Object Drawing.Point 590,20
$netConfigSubtext5.text = "• Select the Standby Adapter:"
$netConfigSubtext5.font = $SubTextFont
$netConfigComboBox1 = New-Object System.Windows.Forms.ComboBox
$netConfigComboBox1.Location = New-Object System.Drawing.Size(310,420)
$netConfigComboBox1.Size = New-Object System.Drawing.Size(260,20)
$netConfigComboBox1.Font = $SubTextFont
$netConfigComboBox1.DropDownStyle = "DropDownList"
[void] $netConfigComboBox1.Items.Add("None (All Adapters Active)")
$NetConfiguration = $netConfigList1,$netConfigSubtext5,$netConfigComboBox1
# CREATE FUNCTIONS
Function ListNetAdapters
{
$RemoveItems = #()
$AddItems = #()
for($index =0; $index -lt $netConfigList1.Items.Count; $index++)
{
$test = $netConfigList1.Items | Where-Object { $netConfigList1.Items.IndexOf($index) }
if($netConfigList1.GetItemChecked($index) -AND $netConfigComboBox1.Items -notcontains $test)
{
$AddItems += ,$test
}
ForEach($i in $netConfigComboBox1.Items){
IF(($netConfigList1.CheckedItems -notcontains $i) -AND ($i -ne 'None (All Adapters Active)')){$RemoveItems += ,$i}
}
}
ForEach ($i in $RemoveItems){$netConfigComboBox1.Items.Remove($i)}
ForEach ($i in $AddItems){$netConfigComboBox1.Items.Add($i)}
}
Function AddNetConfiguration
{
ForEach ($i in $NetConfiguration){$form.controls.add($i)}
}
AddNetConfiguration
# DISPLAY FORM
$form.ShowDialog()
Basically, what i'm trying to accomplish is exactly what you would see in the Advanced Settings of a NIC Team in Windows Server 2012/2012 R2. I want the network adapters selected in the CheckedListBox to populate in the ComboBox and be removed if unchecked.
I've installed WMF 4.0 on my Windows 7 PC and this seems to work well, but I get "System.Object[]" in Windows Server 2012. So i'm apparently missing the big picture or doing something wrong.
Windows Server 2012 comes with PowerShell v3.0, you have to make it to WMF4.0
Answer moved from question by editor
I was able to get it working after I fixed the $ListNetAdapters function. I think I was over complicating it before.
Function ListNetAdapters
{
$RemoveItems = #()
$AddItems = #()
ForEach($checkedItem in $netConfigList1.CheckedItems){
IF($netConfigComboBox1.Items -notcontains $checkedItem){$AddItems += ,$checkedItem}
}
ForEach($item2Badded in $AddItems){$netConfigComboBox1.Items.Add($item2Badded)}
ForEach($dropdownItem in $netConfigComboBox1.Items){
IF($netConfigList1.CheckedItems -notcontains $dropdownItem){$RemoveItems += ,$dropdownItem}
}
ForEach($item2Bremoved in $RemoveItems){
IF($item2Bremoved -ne 'None (All Adapters Active)'){$netConfigComboBox1.Items.Remove("$item2Bremoved")}
}
}

Switch statement produces incorrect result

I'm creating a script for our support department and interns. I have a working script but wanted to use a GUI to it a bit easier for our interns. At this moment I'm pulling my hair out right now, I've copied the function below and and would like to have the value of $task1_exec. But when I try to put the return $Result in a variable the $Task1 variable is printed not the $Task1_exec one.
$FormTitle = "Formtitle"
$ScriptPath = $(get-location).Path;
$task1 = "Task 1"
$task1_exec = "Perform task 1"
$task2 = "Task 2"
$task2_exec = "Perform task 2"
$task3 = "Task 3"
$task3_exec = "Perform task 3"
$task4 = "Task 4"
$task4_exec = "Perform task 4"
function Prompt-SelectionList
{
Param(
[Parameter(Position=0,Mandatory=$true)][string]$Description,
[Parameter(Position=1,Mandatory=$true)][string[]]$List
)
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")
$Form = New-Object System.Windows.Forms.Form
$Form.Text = $FormTitle
$Form.Size = New-Object System.Drawing.Size(500,450) #(300,200)
$Form.StartPosition = "CenterScreen"
$btnOK = New-Object System.Windows.Forms.Button
$btnOK.Location = New-Object System.Drawing.Size(125,375)
$btnOK.Size = New-Object System.Drawing.Size(125,25)
$btnOK.Text = "Run..."
$Form.Controls.Add($btnOK)
$btnCancel = New-Object System.Windows.Forms.Button
$btnCancel.Location = New-Object System.Drawing.Size(250,375)
$btnCancel.Size = New-Object System.Drawing.Size(125,25)
$btnCancel.Text = "Exit"
$btnCancel.Add_Click({ $script:Result = $null; $Form.Close() })
$Form.Controls.Add($btnCancel)
$Label = New-Object System.Windows.Forms.Label
$Label.Location = New-Object System.Drawing.Size(10,20)
$Label.Size = New-Object System.Drawing.Size(480,20)
$Label.Text = $Description
$Form.Controls.Add($Label)
$ListBox = New-Object System.Windows.Forms.ListBox
$ListBox.Location = New-Object System.Drawing.Size(10,40)
$ListBox.Size = New-Object System.Drawing.Size(460,330)
$List | ForEach-Object { [void] $ListBox.Items.Add($_) }
$Form.Controls.Add($ListBox)
$Form.KeyPreview = $True
$Form.Add_KeyDown({ if ($_.KeyCode -eq "Enter") { $script:Result = $ListBox.SelectedItem; $Form.Close() }})
$Form.Add_KeyDown({ if ($_.KeyCode -eq "Escape") { $script:Result = $null; $Form.Close() }})
$btnOK.Add_Click({ $script:Result = $ListBox.SelectedItem; $Form.Close() })
$Form.Topmost = $True
$Form.Add_Shown({ $Form.Activate() })
[void] $Form.ShowDialog()
return $Result
}
function Do-PromptTask
{
switch -wildcard (Prompt-SelectionList "Chose task to run:" #($task1,$task2,$task3,$task4))
{
$task1{$task1_exec}
$task2{$task2_exec}
$Task3{$task3_exec}
$Task4{$task4_exec}
""{Exit} #End Selection (cancel selected)
# "*"{Do-PromptTask} #Keep prompting until "cancel" selected
}
}
Do-PromptTask
My wish is that I could return $task1_exec to a variable so when Do-PromptTask is finished the return can be used to call another script
. ".\Bin\$Result.ps1"
It looks like you're on the right track.
Let's pretend I run Do-PromptTask, chose Task 1, and click Run...
The $result variable from Prompt-SelectionList is passed back to the Switch statement and is out of scope at this point. The switch is doing its job and matching the conditional which then prints $task1_exec, but $result is of no use at this point. If you want to store $task1_exec as a variable, you'd need to set something equal to it. However, I will say you could just act on it in the switch statement without storing it in a variable, if that makes sense.
Less code approach...
function Do-PromptTask
{
switch -wildcard (Prompt-SelectionList "Chose task to run:" #($task1,$task2,$task3,$task4))
{
$task1{Invoke-Expression $task1_exec}
$task2{Invoke-Expression $task2_exec}
$Task3{Invoke-Expression $task3_exec}
$Task4{Invoke-Expression $task4_exec}
""{Exit} #End Selection (cancel selected)
# "*"{Do-PromptTask} #Keep prompting until "cancel" selected
}
}
If you're set on storing the variable, you could do something like this...
function Do-PromptTask
{
switch -wildcard (Prompt-SelectionList "Chose task to run:" #($task1,$task2,$task3,$task4))
{
$task1{$task_result = $task1_exec}
$task2{$task_result = $task2_exec}
$Task3{$task_result = $task3_exec}
$Task4{$task_result = $task4_exec}
""{Exit} #End Selection (cancel selected)
# "*"{Do-PromptTask} #Keep prompting until "cancel" selected
}
Invoke-Expression $task_result
}

Validating Event Not Firing

I'm having real trouble getting the validating event to fire. I have created a very simple windows form to demonstrate the problem. The form contains two textboxes and I'd expect the validating event to fire when the tab key is pressed in the first textbox, but it isn't. I'm using Powershell V4.0, running under Windows 7 Professional SP1. Code follows:-
Function ValidateField( [string]$FieldValue )
{
Write-Host "ValidateField: Function Entered"
if ( $FieldValue -eq $Null -Or $FieldValue.Trim().Length -eq 0 ) { Return $True } else { Return $False }
}
Function GenerateForm
{
Write-Host "GenerateForm: Function Entered"
[Reflection.Assembly]::LoadWithPartialName( "System.Windows.Forms" ) | Out-Null
[Reflection.Assembly]::LoadWithPartialName( "System.Drawing" ) | Out-Null
$Form = New-Object System.Windows.Forms.Form ; $IFWS = New-Object System.Windows.Forms.FormWindowState
$Code = New-Object System.Windows.Forms.TextBox ; $Desc = New-Object System.Windows.Forms.TextBox
$Form.ClientSize = New-Object System.Drawing.Size( 400,200 )
$Form.StartPosition = "CenterScreen" ; $Form.add_Load( $FormLoad )
$OnLoadForm_StateCorrection = { $Form.WindowState = $IFWS }
$Code.DataBindings.DefaultDataSourceUpdateMode = 0 ; $Code.Location = New-Object System.Drawing.Size( 10,10 )
$Code.Size = New-Object System.Drawing.Size( 40,20 ) ; $Code.CausesValidation = $True
$Code_Validating = [System.ComponentModel.CancelEventHandler] {
{ $Result = ( ValidateField $Code.Text )
if ( $Result -eq $True ) { $_.Cancel = $True } }
}
$Form.Controls.Add( $Code )
$Desc.DataBindings.DefaultDataSourceUpdateMode = 0 ; $Desc.Location = New-Object System.Drawing.Size( 100,10 )
$Desc.Size = New-Object System.Drawing.Size( 169,20 ) ; $Form.Controls.Add( $Desc )
$IFWS = $Form.WindowState ; $Form.add_Load( $OnLoadForm_StateCorrection ) ; $Form.ShowDialog() | Out-Null
}
GenerateForm
It may well be that I'm just missing something very very simple - but this has been driving me mad for 3 days now, so any help gratefully accepted.
I don't see where you are connecting to the Validating event. Replace your $Code_Validating assignment with this:
$Code.add_Validating({
$result = ValidateField $sender.Text
if ($result) {$eventArgs.Cancel = $true}
})

Resources