PowerShell Winforms Textbox updates on other input but overwriteable - winforms

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.

Related

Copy Azure Storage Table Service data to SQL Server

How can I copy huge amounts of data from Azure Storage Table Service to SQL Server using PowerShell?
AzTable which Microsoft recommends using does not support incremental load without underlying information about partition keys, and the documentation website is down...:
https://learn.microsoft.com/en-us/azure/storage/tables/table-storage-how-to-use-powershell
I am answering this question myself, because I have lots of trouble findind a solution online, and would like to help other people with this crap.
$StorageAccountResourceGroup = "MyResourceGroup"
$StorageAccountName = "MyStorageAccount"
$TableName = "MyStorageTableName"
$SqlConnectionString = "MySqlConnectionString"
$BulkCopy = [System.Data.SqlClient.SqlBulkCopy]::new()
$BulkCopy.DestinationTableName = "[myschema].[mytablename]"
$DataTable = <<Generate datatable from SQL-table>> # Code not included
Connect-AzAccount
$StorageAccountKey = (Get-AzStorageAccountKey -ResourceGroupName $StorageAccountResourceGroup -AccountName $StorageAccountName | Where-Object -FilterScript {$_.KeyName -eq "Key1"}).Value
$Context = New-AzStorageContext -StorageAccountName $StorageAccountName -StorageAccountKey $StorageAccountKey
$CloudTable = (Get-AzStorageTable -Context $Context -Name $TableName).CloudTable
$TableQuery = [Microsoft.Azure.Cosmos.Table.TableQuery]::new()
$Token = $null
BulkCounter = 0
do{
$ReturnObject = $CloudTable.ExecuteQuerySegmented($TableQuery, $Token)
$Token = $ReturnObject.ContinuationToken
foreach($Entry in $ReturnObject){
$Row = $DataTable.NewRow()
foreach($Column in $DataTable.Columns){
if($Column.ColumnName -eq "TimeStamp"){
$Value = $Entry.TimeStamp
} elseif($Column.ColumnName -eq "RowKey"){
$Value = $Entry.RowKey
} elseif($Column.ColumnName -eq "PartitionKey"){
$Value = $Entry.PartitionKey
} else {
if($Column.DataType -eq [System.Decimal]){
$Value = $Entry.Properties.$($Column.ColumnName).DoubleValue
} elseif($Column.DataType -eq [System.String]){
$Value = $Entry.Properties.$($Column.ColumnName).StringValue
} elseif($Column.DataType -eq [System.Guid]){
$Value = $Entry.Properties.$($Column.ColumnName).GuidValue
} elseif($Column.DataType -eq [System.datetimeoffset]){
$Value = $Entry.Properties.$($Column.ColumnName).DateTimeOffsetValue
} elseif($Column.DataType -eq [System.Int32]){
$Value = $Entry.Properties.$($Column.ColumnName).Int32Value
} elseif($Column.DataType -eq [System.Int64]){
$Value = $Entry.Properties.$($Column.ColumnName).Int64Value
} elseif($Column.DataType -eq [System.Boolean]){
$Value = $Entry.Properties.$($Column.ColumnName).BooleanValue
} elseif($Column.DataType -eq [System.Binary]){
$Value = $Entry.Properties.$($Column.ColumnName).BinaryValue
}
}
if([System.String]::IsNullOrWhiteSpace($Value)){
$Value = [System.DBNull]::value
}
$Row.($Column.ColumnName) = $Value
}
$DataTable.Rows.Add($Row)
$Counter++
}
$BulkCounter ++
if($BulkCounter % 25 -eq 0 -and $BulkCounter -ne 0){
$BulkCopy.WriteToServer($Datatable.CreateDataReader()) | Out-Null
$Datatable.Clear() | Out-Null
$BulkCounter = 0
}
} while ($Token)
if($Datatable.rows.count -gt 0){
$BulkCopy.WriteToServer($Datatable.CreateDataReader()) | Out-Null
$Datatable.Clear() | Out-Null
}
Here is also some functions for automatically generating tables from storage account tables:
function ConvertTo-SqlTypeFromEDM {
param (
$EDMType
)
if($EDMType -eq "String"){
return "varchar(100)"
} elseif($EDMType -eq "Guid"){
return "uniqueidentifier"
} elseif ($EDMType -eq "DateTime"){
return "datetimeoffset(0)"
} elseif ($EDMType -eq "Binary"){
return "varbinary(max)"
} elseif ($EDMType -eq "Int32"){
return "int"
} elseif ($EDMType -eq "Int64"){
return "long"
} elseif ($EDMType -eq "Double"){
return "decimal(25,5)"
} elseif ($EDMType -eq "Boolean"){
return "bit"
} else {
throw "Tybe $EDMType not implemented"
}
}
function Get-SqlQueryFromStorageTableSerivce {
param(
$CloudTable,
$SchemaName
)
$Query = [Microsoft.Azure.Cosmos.Table.TableQuery]::new()
$Query.TakeCount = 1
$Token = $null
$Result = $CloudTable.ExecuteQuerySegmented($Query, $Token)
$TableName = $CloudTable.Name
$TableString = "DROP TABLE IF EXISTS [$SchemaName].[$TableName]`n"
$TableString += "CREATE TABLE [$SchemaName].[$TableName] (`n`t"
$ColumnString = #()
$TableKeys = #()
if($Result.PartitionKey){
$ColumnString += "[PartitionKey] varchar(100) NOT NULL"
$TableKeys += "[PartitionKey]"
}
if($Result.RowKey){
$ColumnString += "[RowKey] varchar(100) NOT NULL"
$TableKeys += "[RowKey]"
}
if($Result.Timestamp){
$ColumnString += "[Timestamp] datetimeoffset(0) NULL"
}
foreach($Column in $Result.Properties.Keys){
$ColumnString += "[$Column] $(ConvertTo-SqlTypeFromEDM -EDMType $Result.Properties.$Column.PropertyType) NULL"
}
$TableString += $ColumnString -join ",`n`t"
$TableString += "`nCONSTRAINT [PK_1_$($TableName)_1] PRIMARY KEY CLUSTERED`n"
$TableString += "(`n`t" + ($TableKeys -join ",`n`t")
$TableString += "`n)WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF, DATA_COMPRESSION = PAGE) ON [PRIMARY]"
$TableString += "`n) ON [PRIMARY]`n"
return $TableString
}

New-Object : Cannot bind parameter 'Property'. Cannot convert the "" value of type PSCustomObject to type IDictionary

I'm having a hard time converting results from Invoke-SqlCmd to a PSCustomobject.
So, I input my query and SQL server, then I run the Invoke-SqlCmd function, and then I try to add data from that (the database logical name, and the autogrowth status) to my PSCustomobject, so I can return it back to my modules public function.
$sqlinstance = "---"
$query = "---"
if ($sqlInstance -match "---") {
$dbAutogrowIGP = Invoke-Sqlcmd -Query $query -ServerInstance $sqlInstance
if ($dbAutogrowIGP.Growth -gt 100 -and $dbAutogrowIGP.Growth -lt 500) {
$autogrowStatus = [PSCustomObject]#{
'SQL_Instance' = $dbAutogrowIGP.LogicalName
'Check' = "Autogrow"
'Status' = "green"
'Status_reason' = ""
}
New-Object -Type Dictionary -Property $autogrowStatus
}
foreach ($db in $dbAutogrowIGP) {
if ($db.Growth -lt 100 -or $db.Growth -gt 500 -and $db.Growth -notlike "%") {
$autogrowStatus = [PSCustomObject]#{
'SQL_Instance' = $db.LogicalName
'Check' = "Autogrow"
'Status' = "red"
'Status_reason' = "$($db.LogicalName) has autogrowth set to $($db.Growth)."
}
New-Object -Type Dictionary -Property $autogrowStatus
}
if ($db.Growth -like "%") {
$autogrowStatus = [PSCustomObject]#{
'SQL_Instance' = $db.LogicalName
'Check' = "Autogrow"
'Status' = "yellow"
'Status_reason' = "$($db.LogicalName) has autogrowth set percentually, it should be an absolute number."
}
New-Object -Type Dictionary -Property $autogrowStatus
}
}
}
return $autogrowStatus
I've debugged it, and I've noticed it fails on the New-object call. I've tried both Dictionary and PSObject/PSCustomObject - however neither works
In my other functions, this works as expected, however in those, I'm using dbatools to make a call.
$getLogSizeIGP = Get-DbaDbLogSpace -sqlInstance $sqlInstance
if ($getLogSizeIGP.LogSize.Gigabyte -lt 10 -and $getLogSizeIGP.LogSpaceUsedPercent -lt 50) {
$logStatus = #{
'SQL_Instance' = $getLogSizeIGP.SqlInstance
'Check' = "Log_size"
'Status' = [gmEnvStatuses]::green
'Status_reason' = ""
}
New-Object -Type PSObject -Property $logStatus
}
How would I go about solving this issue?
This is the whole error message:
New-Object : Cannot bind parameter 'Property'. Cannot convert the "#{SQL_Instance=Maintenance_log; Check=Autogrow; Status=red; Status_reason=Maintenance_log has autogrowth set to 10%.}" value of type "System.Management.Automation.PSCustomObject" to type
"System.Collections.IDictionary".
At C:\Users\---\Desktop\autogrowth.ps1:50 char:55
+ New-Object -Type Dictionary -Property $autogrowStatus
+ ~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [New-Object], ParameterBindingException
+ FullyQualifiedErrorId : CannotConvertArgumentNoMessage,Microsoft.PowerShell.Commands.NewObjectCommand
Thanks!
The easiest way of collecting this data is by capturing it all at the beginning of the if ($sqlInstance -match "---") { statement and simply output the PsCustomObjects without trying to convert them.
Something like
$sqlinstance = "---"
$query = "---"
$autogrowStatus = if ($sqlInstance -match "---") {
$dbAutogrowIGP = Invoke-Sqlcmd -Query $query -ServerInstance $sqlInstance
if ($dbAutogrowIGP.Growth -gt 100 -and $dbAutogrowIGP.Growth -lt 500) {
# output the object to be captured in the $autogrowStatus variable
[PSCustomObject]#{
'SQL_Instance' = $dbAutogrowIGP.LogicalName
'Check' = "Autogrow"
'Status' = "green"
'Status_reason' = ""
}
}
foreach ($db in $dbAutogrowIGP) {
if ($db.Growth -lt 100 -or $db.Growth -gt 500 -and $db.Growth -notlike "%") {
[PSCustomObject]#{
'SQL_Instance' = $db.LogicalName
'Check' = "Autogrow"
'Status' = "red"
'Status_reason' = "$($db.LogicalName) has autogrowth set to $($db.Growth)."
}
}
if ($db.Growth -like "%") {
[PSCustomObject]#{
'SQL_Instance' = $db.LogicalName
'Check' = "Autogrow"
'Status' = "yellow"
'Status_reason' = "$($db.LogicalName) has autogrowth set percentually, it should be an absolute number."
}
}
}
}
return $autogrowStatus
The variable $autogrowStatus will become an array of PSCustomObjects to handle in the rest of your functions.
Hope this helps

PowerShell Winforms MoveUp/MoveDown

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() } }

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")}
}
}

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